codeforces-1144 (div3)
赛后经验:div3过于简单,以后不做了
A.存在以下情况即为NO
1.存在相同字母 2.最大字母-最小字母 != 字符串长度
#include <map> #include <set> #include <ctime> #include <cmath> #include <queue> #include <stack> #include <vector> #include <string> #include <cstdio> #include <cstdlib> #include <cstring> #include <sstream> #include <iostream> #include <algorithm> #include <functional> using namespace std; #define For(i, x, y) for(int i=x;i<=y;i++) #define _For(i, x, y) for(int i=x;i>=y;i--) #define Mem(f, x) memset(f,x,sizeof(f)) #define Sca(x) scanf("%d", &x) #define Sca2(x,y) scanf("%d%d",&x,&y) #define Sca3(x,y,z) scanf("%d%d%d",&x,&y,&z) #define Scl(x) scanf("%lld",&x); #define Pri(x) printf("%d\n", x) #define Prl(x) printf("%lld\n",x); #define CLR(u) for(int i=0;i<=N;i++)u[i].clear(); #define LL long long #define ULL unsigned long long #define mp make_pair #define PII pair<int,int> #define PIL pair<int,long long> #define PLL pair<long long,long long> #define pb push_back #define fi first #define se second typedef vector<int> VI; int read(){int x = 0,f = 1;char c = getchar();while (c<'0' || c>'9'){if (c == '-') f = -1;c = getchar();} while (c >= '0'&&c <= '9'){x = x * 10 + c - '0';c = getchar();}return x*f;} const double eps = 1e-9; const int maxn = 1e5 + 10; const int INF = 0x3f3f3f3f; const int mod = 1e9 + 7; int N,M,K; bool vis[maxn]; char str[maxn]; int main(){ int T = read(); while(T--){ scanf("%s",str); int l = strlen(str); int MIN = INF,MAX = 0,flag = 1; for(int i = 0 ; i < 30; i ++) vis[i] = 0; for(int i = 0 ; i < l ; i ++){ if(vis[str[i] - 'a']){ flag = 0; continue; } vis[str[i] - 'a'] = 1; MIN = min(MIN,str[i] - 'a'); MAX = max(MAX,str[i] - 'a'); } if(MAX - MIN + 1 == l && flag){ puts("Yes"); }else{ puts("No"); } } return 0; }
B.设奇数字母cnt1个,偶数字母cnt2个
假设cnt1 >= cnt2 最多留下(cnt1 - cnt2 - 1)个奇数字母,偶数同理
取最小的保留就可以了
#include <map> #include <set> #include <ctime> #include <cmath> #include <queue> #include <stack> #include <vector> #include <string> #include <cstdio> #include <cstdlib> #include <cstring> #include <sstream> #include <iostream> #include <algorithm> #include <functional> using namespace std; #define For(i, x, y) for(int i=x;i<=y;i++) #define _For(i, x, y) for(int i=x;i>=y;i--) #define Mem(f, x) memset(f,x,sizeof(f)) #define Sca(x) scanf("%d", &x) #define Sca2(x,y) scanf("%d%d",&x,&y) #define Sca3(x,y,z) scanf("%d%d%d",&x,&y,&z) #define Scl(x) scanf("%lld",&x); #define Pri(x) printf("%d\n", x) #define Prl(x) printf("%lld\n",x); #define CLR(u) for(int i=0;i<=N;i++)u[i].clear(); #define LL long long #define ULL unsigned long long #define mp make_pair #define PII pair<int,int> #define PIL pair<int,long long> #define PLL pair<long long,long long> #define pb push_back #define fi first #define se second typedef vector<int> VI; int read(){int x = 0,f = 1;char c = getchar();while (c<'0' || c>'9'){if (c == '-') f = -1;c = getchar();} while (c >= '0'&&c <= '9'){x = x * 10 + c - '0';c = getchar();}return x*f;} const double eps = 1e-9; const int maxn = 2010; const int INF = 0x3f3f3f3f; const int mod = 1e9 + 7; int N,M,K; int even[maxn],odd[maxn]; int main(){ Sca(N); int cnt1 = 0,cnt2 = 0; for(int i = 1; i <= N ; i ++){ int x = read(); if(x & 1) odd[++cnt1] = x; else even[++cnt2] = x; } sort(odd + 1,odd + cnt1 + 1); sort(even + 1,even + 1 + cnt2); if(abs(cnt1 - cnt2) <= 1){ puts("0"); }else if(cnt1 > cnt2){ LL sum = 0; for(int i = 1; i <= cnt1 - cnt2 - 1;i ++) sum += odd[i]; Prl(sum); }else{ LL sum = 0; for(int i = 1; i <= cnt2 - cnt1 - 1;i ++) sum += even[i]; Prl(sum); } return 0; }
C.很显然一个数出现次数超过3次就NO
第一个数列输出所有次数 >= 1的数
第二个数列输出所有次数 >= 2的数即可
#include <map> #include <set> #include <ctime> #include <cmath> #include <queue> #include <stack> #include <vector> #include <string> #include <cstdio> #include <cstdlib> #include <cstring> #include <sstream> #include <iostream> #include <algorithm> #include <functional> using namespace std; #define For(i, x, y) for(int i=x;i<=y;i++) #define _For(i, x, y) for(int i=x;i>=y;i--) #define Mem(f, x) memset(f,x,sizeof(f)) #define Sca(x) scanf("%d", &x) #define Sca2(x,y) scanf("%d%d",&x,&y) #define Sca3(x,y,z) scanf("%d%d%d",&x,&y,&z) #define Scl(x) scanf("%lld",&x); #define Pri(x) printf("%d\n", x) #define Prl(x) printf("%lld\n",x); #define CLR(u) for(int i=0;i<=N;i++)u[i].clear(); #define LL long long #define ULL unsigned long long #define mp make_pair #define PII pair<int,int> #define PIL pair<int,long long> #define PLL pair<long long,long long> #define pb push_back #define fi first #define se second typedef vector<int> VI; int read(){int x = 0,f = 1;char c = getchar();while (c<'0' || c>'9'){if (c == '-') f = -1;c = getchar();} while (c >= '0'&&c <= '9'){x = x * 10 + c - '0';c = getchar();}return x*f;} const double eps = 1e-9; const int maxn = 2e5 + 10; const int INF = 0x3f3f3f3f; const int mod = 1e9 + 7; int N,M,K; int a[maxn]; int ans[maxn]; int main(){ Sca(N); int MAX = -1,MIN = INF; bool flag = 1; for(int i = 1; i <= N; i ++){ int x = read(); a[x]++; if(a[x] > 2) flag = 0; MAX = max(MAX,x); MIN = min(MIN,x); } if(!flag){ puts("NO"); return 0; } puts("YES"); int top = 0; for(int i = MIN; i <= MAX; i ++){ if(a[i]){ a[i]--; ans[++top] = i; } } Pri(top); for(int i = 1; i <= top; i ++) printf("%d ",ans[i]); puts(""); top = 0; for(int i = MAX; i >= MIN; i --){ if(a[i]) ans[++top] = i; } Pri(top); for(int i = 1; i <= top; i ++) printf("%d ",ans[i]); puts(""); return 0; }
D.仔细一看就会发现操作就是把一个数变为相邻的一个数。
那么出现最多次数的数不变,其余的都变成他就可以了。
#include <map> #include <set> #include <ctime> #include <cmath> #include <queue> #include <stack> #include <vector> #include <string> #include <cstdio> #include <cstdlib> #include <cstring> #include <sstream> #include <iostream> #include <algorithm> #include <functional> using namespace std; #define For(i, x, y) for(int i=x;i<=y;i++) #define _For(i, x, y) for(int i=x;i>=y;i--) #define Mem(f, x) memset(f,x,sizeof(f)) #define Sca(x) scanf("%d", &x) #define Sca2(x,y) scanf("%d%d",&x,&y) #define Sca3(x,y,z) scanf("%d%d%d",&x,&y,&z) #define Scl(x) scanf("%lld",&x); #define Pri(x) printf("%d\n", x) #define Prl(x) printf("%lld\n",x); #define CLR(u) for(int i=0;i<=N;i++)u[i].clear(); #define LL long long #define ULL unsigned long long #define mp make_pair #define PII pair<int,int> #define PIL pair<int,long long> #define PLL pair<long long,long long> #define pb push_back #define fi first #define se second typedef vector<int> VI; int read(){int x = 0,f = 1;char c = getchar();while (c<'0' || c>'9'){if (c == '-') f = -1;c = getchar();} while (c >= '0'&&c <= '9'){x = x * 10 + c - '0';c = getchar();}return x*f;} const double eps = 1e-9; const int maxn = 2e5 + 10; const int INF = 0x3f3f3f3f; const int mod = 1e9 + 7; int N,M,K; int a[maxn]; int num[maxn]; int main(){ Sca(N); int MAX = 0; for(int i = 1; i <= N ; i ++){ Sca(a[i]); num[a[i]]++; if(num[MAX] < num[a[i]]) MAX = a[i]; } int root = 1; int ans = 0; Pri(N - num[MAX]); for(int i = 1; i <= N ; i ++){ if(a[i] == MAX){ root = i; break; } } for(int i = root + 1; i <= N; i ++){ if(a[i] > a[i - 1]) printf("2 %d %d\n",i,i - 1); else if(a[i] < a[i - 1]) printf("1 %d %d\n",i,i - 1); a[i] = a[i - 1]; } for(int i = root - 1; i >= 1; i --){ if(a[i] > a[i + 1]) printf("2 %d %d\n",i,i + 1); else if(a[i] < a[i + 1]) printf("1 %d %d\n",i,i + 1); a[i] = a[i + 1]; } return 0; }
E.模拟26进制加减法即可。具体操作就是(a + b) / 2
#include <map> #include <set> #include <ctime> #include <cmath> #include <queue> #include <stack> #include <vector> #include <string> #include <cstdio> #include <cstdlib> #include <cstring> #include <sstream> #include <iostream> #include <algorithm> #include <functional> using namespace std; #define For(i, x, y) for(int i=x;i<=y;i++) #define _For(i, x, y) for(int i=x;i>=y;i--) #define Mem(f, x) memset(f,x,sizeof(f)) #define Sca(x) scanf("%d", &x) #define Sca2(x,y) scanf("%d%d",&x,&y) #define Sca3(x,y,z) scanf("%d%d%d",&x,&y,&z) #define Scl(x) scanf("%lld",&x); #define Pri(x) printf("%d\n", x) #define Prl(x) printf("%lld\n",x); #define CLR(u) for(int i=0;i<=N;i++)u[i].clear(); #define LL long long #define ULL unsigned long long #define mp make_pair #define PII pair<int,int> #define PIL pair<int,long long> #define PLL pair<long long,long long> #define pb push_back #define fi first #define se second typedef vector<int> VI; int read(){int x = 0,f = 1;char c = getchar();while (c<'0' || c>'9'){if (c == '-') f = -1;c = getchar();} while (c >= '0'&&c <= '9'){x = x * 10 + c - '0';c = getchar();}return x*f;} const double eps = 1e-9; const int maxn = 2e5 + 10; const int INF = 0x3f3f3f3f; const int mod = 1e9 + 7; int N,M,K; char a[maxn],b[maxn]; int c[maxn]; int main(){ N = read(); scanf("%s%s",a + 1,b + 1); for(int i = N ; i >= 1; i--){ c[i] += b[i] + a[i] - 'a' - 'a' + 2; while(c[i] > 27){ c[i] -= 26; c[i - 1]++; } } int zero = 1; for(int i = 0 ; i <= N ; i ++){ if(c[i] & 1){ c[i]--; c[i + 1] += 26; } c[i] /= 2; if(c[i]) zero = 0; if(!zero) printf("%c",c[i] + 'a' - 1); } return 0; }
F.意识到一个点不会即有入度又有出度,那么所有点就分为了出度点和入度点。
直接图上染色即可。
#include <map> #include <set> #include <ctime> #include <cmath> #include <queue> #include <stack> #include <vector> #include <string> #include <cstdio> #include <cstdlib> #include <cstring> #include <sstream> #include <iostream> #include <algorithm> #include <functional> using namespace std; #define For(i, x, y) for(int i=x;i<=y;i++) #define _For(i, x, y) for(int i=x;i>=y;i--) #define Mem(f, x) memset(f,x,sizeof(f)) #define Sca(x) scanf("%d", &x) #define Sca2(x,y) scanf("%d%d",&x,&y) #define Sca3(x,y,z) scanf("%d%d%d",&x,&y,&z) #define Scl(x) scanf("%lld",&x); #define Pri(x) printf("%d\n", x) #define Prl(x) printf("%lld\n",x); #define CLR(u) for(int i=0;i<=N;i++)u[i].clear(); #define LL long long #define ULL unsigned long long #define mp make_pair #define PII pair<int,int> #define PIL pair<int,long long> #define PLL pair<long long,long long> #define pb push_back #define fi first #define se second typedef vector<int> VI; int read(){int x = 0,f = 1;char c = getchar();while (c<'0' || c>'9'){if (c == '-') f = -1;c = getchar();} while (c >= '0'&&c <= '9'){x = x * 10 + c - '0';c = getchar();}return x*f;} const double eps = 1e-9; const int maxn = 2e5 + 10; const int INF = 0x3f3f3f3f; const int mod = 1e9 + 7; int N,M,K; struct Edge{ int to,next; }edge[maxn * 2]; int head[maxn],tot; void init(){ for(int i = 0 ; i <= N; i ++) head[i] = -1; tot = 0; } void add(int u,int v){ edge[tot].to = v; edge[tot].next = head[u]; head[u] = tot++; } int color[maxn]; bool flag = 1; void dfs(int t){ if(!flag) return; for(int i = head[t]; ~i ; i = edge[i].next){ int v = edge[i].to; if(color[v] == color[t]){ flag = 0; return; } if(color[v] == 3 - color[t]) continue; color[v] = 3 - color[t]; dfs(v); } } PII E[maxn]; int main(){ Sca2(N,M); init(); for(int i = 1; i <= M; i ++){ int u = read(),v = read(); add(u,v); add(v,u); E[i] = mp(u,v); } for(int i = 1; i <= N && flag; i ++){ if(!color[i]){ color[i] = 1; dfs(i); } } if(!flag){ puts("NO"); return 0; }else{ puts("YES"); } for(int i = 1; i <= M ; i ++){ if(color[E[i].fi] == 1) printf("1"); else printf("0"); } return 0; }
G.题目的一个子问题是序列中的一个区间能否分为递增和递减
意识到一个区间最小的点,只能作为递增的起点或者递减的终点,在知道了这个条件下,另一边就已知必须递增或者递减。
预处理出每个点为起点的最大递增终点和最大递减终点。
用solve(l,r,lMIN,lMAX,rMIN,rMAX)表示在l到r这段区间内,递减段的数字被限制在lMIN到lMAX内,递增段的数字被限制在rMIN,rMAX内,在此基础上求是否可行。
#include <map> #include <set> #include <ctime> #include <cmath> #include <queue> #include <stack> #include <vector> #include <string> #include <cstdio> #include <cstdlib> #include <cstring> #include <sstream> #include <iostream> #include <algorithm> #include <functional> using namespace std; #define For(i, x, y) for(int i=x;i<=y;i++) #define _For(i, x, y) for(int i=x;i>=y;i--) #define Mem(f, x) memset(f,x,sizeof(f)) #define Sca(x) scanf("%d", &x) #define Sca2(x,y) scanf("%d%d",&x,&y) #define Sca3(x,y,z) scanf("%d%d%d",&x,&y,&z) #define Scl(x) scanf("%lld",&x); #define Pri(x) printf("%d\n", x) #define Prl(x) printf("%lld\n",x); #define CLR(u) for(int i=0;i<=N;i++)u[i].clear(); #define LL long long #define ULL unsigned long long #define mp make_pair #define PII pair<int,int> #define PIL pair<int,long long> #define PLL pair<long long,long long> #define pb push_back #define fi first #define se second typedef vector<int> VI; int read(){int x = 0,f = 1;char c = getchar();while (c<'0' || c>'9'){if (c == '-') f = -1;c = getchar();} while (c >= '0'&&c <= '9'){x = x * 10 + c - '0';c = getchar();}return x*f;} const double eps = 1e-9; const int maxn = 8e5 + 10; const int INF = 0x3f3f3f3f; const int mod = 1e9 + 7; int N,M,K; int a[maxn],Hash[maxn]; struct tree{ int l,r,MIN; }tree[maxn << 2]; void Pushup(int t){ if(a[tree[t << 1].MIN] < a[tree[t << 1 | 1].MIN]) tree[t].MIN = tree[t << 1].MIN; else tree[t].MIN = tree[t << 1 | 1].MIN; } void Build(int t,int l,int r){ tree[t].l = l; tree[t].r = r; if(l == r){ tree[t].MIN = l; return; } int m = l + r >> 1; Build(t << 1,l,m); Build(t << 1 | 1,m + 1,r); Pushup(t); } int query(int t,int l,int r){ if(l <= tree[t].l && tree[t].r <= r) return tree[t].MIN; int m = tree[t].l + tree[t].r >> 1; if(r <= m) return query(t << 1,l,r); else if(l > m) return query(t << 1 | 1,l,r); else{ int p1 = query(t << 1,l,m),p2 = query(t << 1 | 1,m + 1,r); if(a[p1] > a[p2]) return p2; return p1; } } int ans[maxn]; int radd[maxn],rdel[maxn]; bool solve(int L,int R,int lMIN,int lMAX,int rMIN,int rMAX){ if(L > R) return true; if(L == R){ if(rMIN < a[L] && a[L] < rMAX){ ans[L] = 0; return true; } if(lMIN < a[L] && a[L] < lMAX){ ans[L] = 1; return true; } return false; } int p = query(1,L,R); if(lMIN < a[p] && a[p] < lMAX && (p == R || (radd[p + 1] >= R && a[p + 1] > rMIN && a[p + 1] < rMAX && a[R] < rMAX && a[R] > rMIN))){ if(solve(L,p - 1,a[p],lMAX,rMIN,p == R?rMAX:a[p + 1])){ ans[p] = 1; for(int j = p + 1; j <= R; j ++) ans[j] = 0; return true; } } if(rMIN < a[p] && a[p] < rMAX && (p == L || (rdel[L] >= p - 1 && a[L] > lMIN && a[L] < lMAX && a[p - 1] < lMAX && a[p - 1] > lMIN))){ if(solve(p + 1,R,lMIN,p == L?lMAX:a[p - 1],a[p],rMAX)){ ans[p] = 0; for(int j = L; j <= p - 1; j ++) ans[j] = 1; return true; } } return false; } int main(){ Sca(N); for(int i = 1; i <= N ; i ++) a[i] = read(); radd[N] = rdel[N] = N; for(int i = N - 1; i >= 1; i --){ if(a[i] < a[i + 1]) radd[i] = radd[i + 1]; else radd[i] = i; if(a[i] > a[i + 1]) rdel[i] = rdel[i + 1]; else rdel[i] = i; } Build(1,1,N); if(solve(1,N,-INF,INF,-INF,INF)){ puts("YES"); for(int i = 1; i <= N ; i ++) printf("%d ",ans[i]); }else{ puts("NO"); } return 0; }