A. Plus One on the Subset
B. Make AP
C. Division by Two and Permutation
D. Palindromes Coloring
E. Masha-forgetful
F. Interacdive Problem
G. MinOr Tree
就是最小值逐步增加到最大值的过程。
int main()
{int t;scanf("%d", &t);for(int _ = 1;_ <= t;_ ++){int n, mi = 1e9, ma = 0, x;scanf("%d", &n);while(n --) scanf("%d", &x), mi = min(mi, x), ma = max(ma, x);cout<<ma-mi<<endl;}return 0;
}
暴力枚举吧。
int main()
{int t;scanf("%d", &t);for(int _ = 1;_ <= t;_ ++){int a, b, c;scanf("%d%d%d", &a, &b, &c);if((a+c&1) == 0 && (a+c>>1)%b == 0) P(1);else if(2*b > c && (2*b-c)%a == 0) P(1);else if(2*b > a && (2*b-a)%c == 0) P(1);else P(0);}return 0;
}
一颗二叉树,贪心从上往下,写麻烦了,下面有简单的。哎
// 额,很难看。。。。
int main()
{int t;scanf("%d", &t);for(int _ = 1;_ <= t;_ ++){int n;scanf("%d", &n);for(int i = 0;i <= n;i ++) num[i] = 0;for(int i = 1;i <= n;i ++){int x;scanf("%d", &x);while(x > n) x >>= 1;num[x] ++;}for(int i = n;i >= 1;i --){if(!num[i]){for(int j = i+1;j <= n;j ++)if(num[j] > 1){int t = j;while(t > i) t >>= 1;if(t == i){num[j] --, num[i] = 1;break;}}if(!num[i]){num[0] = 1;break;}}}P(!num[0]);}return 0;
}// 简化的。
#define P(x) puts((x)?Y1:N1)
#define Y1 "YES"
#define N1 "NO"
using namespace std;
typedef long long LL;
typedef pair<int,int> PII;
const int N = 1e6+10;int num[N];
bool dis[N];int main()
{int t;scanf("%d", &t);for(int _ = 1;_ <= t;_ ++){int n;scanf("%d", &n);for(int i = 0;i <= n;i ++) dis[i] = 0;for(int i = 1;i <= n;i ++){scanf("%d", num+i);while(num[i] > n) num[i] >>= 1;} sort(num+1, num+n+1);for(int i = n;i >= 1;i --){while(num[i] && dis[num[i]]) num[i] >>= 1;dis[num[i]] = 1;if(!num[i]) i = 0; }P(!dis[0]);}return 0;
}
直接分配,
int num[26];
char c[N];int main()
{int t;scanf("%d", &t);for(int _ = 1;_ <= t;_ ++){int n, k;scanf("%d%d%s", &n, &k, c);for(int i = 0;i < 26;i ++) num[i] = 0;for(int i = 0;c[i];i ++) num[c[i]-'a'] ++;int l = 0, r = 0;for(int i = 0;i < 26;i ++) l += num[i]>>1, r += num[i]&1;r += (l%k)*2; // 这句要加上。 l = l/k*2; if(r >= k) l++;printf("%d\n", l);}return 0;
}
不要求最小数目那就可以把 > 3的段 分成 2*x + 3的形式。
先dp一下看可不可以,可以就直接搜索
bool dis[N];
int num[1401];
PII p[1401];
string c;int s(string c){int x = 0;for(auto v:c) x = x*11 + (v-'0'+1); return x;} // 映射成12进制的数 001 != 01 void dfs(int i, int x)
{int t = 0, len = i + 1;if(i == 1 || i == 2) printf("%d\n", x+1);else if(dis[i-2]&&num[s(c.substr(i-1, 2))]) dfs(i-2, x+1), len = 2;else dfs(i-3, x+1), len = 3;t = s(c.substr(i-len+1, len));printf("%d %d %d\n", p[t].first, p[t].second, num[t]);return ;
}
void p1(){puts("-1");return ;}int main()
{int t;scanf("%d", &t);for(int _ = 1;_ <= t;_ ++){int n, k;scanf("%d%d", &n, &k);for(int j = 1;j <= n;j ++){cin>>c;for(int l = 2, x;l <= 3;l ++) for(int i = 0;i <= k-l;i ++)x = s(c.substr(i, l)), num[x] = j, p[x] = {i+1, i+l};}cin>>c;dis[1] = num[s(c.substr(0, 2))]; dis[2] = num[s(c.substr(0, 3))];for(int i = 3;i < k;i ++) // dp 一下 dis[i] = (dis[i-2]&&num[s(c.substr(i-1, 2))])|(dis[i-3]&&num[s(c.substr(i-2, 3))]);dis[k-1] ? dfs(k-1, 0): p1(); // p1 就是为了可以用 ? : 语句 for(int x = 0;x <= 1400;x ++) num[x] = dis[x] = 0;}return 0;
}
模拟,想成一个线段,每次可以把中点放到整除的位置从而把线段减半,然后注意要把mid+1放到整除的位置,因为最后mid = l
int main()
{int n;scanf("%d", &n);int l = 1, r = n-1, t = r-mid; while(l < r){int x;cout<<"+ "<<t<<endl;fflush(stdout); scanf("%d", &x);l += t, r += t;x == r/n ? (l = r/n*n, t = (x+1)*n-mid-1) : (r = r/n*n-1, t = r-mid); }cout<<"! "<<l<<endl; return 0;
}
看答案的,贪心来算。哎
const int N = 1e6+10;vector<PII>G[N];
bool dis[N];
int ans = 0, t = 0;
void dfs(int u)
{dis[u] = 1;for(auto x : G[u])if(!dis[x.first] && (ans|x.second) == ans)dfs(x.first);return ;
}void add(){int u, v, w;scanf("%d%d%d", &u, &v, &w);G[u].push_back({v, w});G[v].push_back({u, w});}
void solve()
{int n, m;scanf("%d%d", &n, &m);for(int i = 1;i <= n;i ++) G[i].clear();while(m --)add();t = 1<<29, ans = (1<<30)-1;while(t){ans -= t;dfs(1);for(int i = 2;i <= n;i ++) dis[1] &= dis[i];if(!dis[1]) ans |= t; memset(dis, 0, n+3);t >>= 1;}printf("%d\n", ans);return ;
}
int main()
{int t;scanf("%d", &t);while(t --) solve();return 0;
}