A.算2,3的因子个数即可
#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 ", x) #define Prl(x) printf("%lld ",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 = 110; const int INF = 0x3f3f3f3f; const int mod = 1e9 + 7; int N,M,K; int main(){ Sca2(N,M); if(M % N){ puts("-1"); return 0; } M /= N; int ans = 0; while(!(M % 2)){ M /= 2; ans++; } while(!(M % 3)){ M /= 3; ans++; } if(M != 1) ans = -1; Pri(ans); return 0; }
B.复制成两倍长找最长连续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 ", x) #define Prl(x) printf("%lld ",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 = 5e5 + 10; const int INF = 0x3f3f3f3f; const int mod = 1e9 + 7; int N,M,K; int a[maxn]; int main(){ Sca(N); for(int i = 1; i <= N ; i ++) a[i] = a[i + N] = read(); N <<= 1; int cnt = 0; int ans = 0; for(int i = 1; i <= N ; i ++){ if(a[i]){ cnt++; ans = max(ans,cnt); }else{ cnt = 0; } } Pri(ans); return 0; }
C.设第一个数字为x,算前缀和pre可知a[i] = x + pre[i],找pre[i]最小的位置即为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 ", x) #define Prl(x) printf("%lld ",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 = 5e5 + 10; const int INF = 0x3f3f3f3f; const int mod = 1e9 + 7; int N,M,K; LL a[maxn]; bool vis[maxn]; bool check(LL x){ if(1 > x || x > N) return false; if(vis[x]) return false; vis[x] = 1; return true; } int main(){ Sca(N); a[1] = 0; LL Min = 0; for(int i = 2; i <= N ; i ++){ Scl(a[i]); a[i] += a[i - 1]; Min = min(Min,a[i]); } a[1] = 1 - Min; bool flag = 1; if(!check(a[1])) flag = 0; for(int i = 2; i <= N && flag; i ++){ a[i] += a[1]; if(!check(a[i])) flag = 0; } if(!flag) puts("-1"); else for(int i = 1; i <= N ; i ++) cout << a[i] << " "; 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 ", x) #define Prl(x) printf("%lld ",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 = 150010; const int INF = 0x3f3f3f3f; const int mod = 1e9 + 7; int N,M,K; vector<int>Q[30]; vector<int>P; char str1[maxn],str2[maxn]; vector<PII>ans; int main(){ Sca(N); scanf("%s%s",str1 + 1,str2 + 1); for(int i = 1; i <= N ; i ++){ if(str1[i] == '?') Q[29].pb(i); else Q[str1[i] - 'a'].pb(i); } for(int i = 1; i <= N ; i ++){ if(str2[i] == '?') P.pb(i); else{ if(!Q[str2[i] - 'a'].empty()){ ans.pb(mp(Q[str2[i] - 'a'].back(),i)); Q[str2[i] - 'a'].pop_back(); }else if(!Q[29].empty()){ ans.pb(mp(Q[29].back(),i)); Q[29].pop_back(); } } } for(int i = 0 ; i < 30 && !P.empty(); i ++){ while(!P.empty() && !Q[i].empty()){ ans.push_back(mp(Q[i].back(),P.back())); P.pop_back(); Q[i].pop_back(); } } Pri(ans.size()); for(int i = 0 ; i < ans.size(); i ++){ printf("%d %d ",ans[i].fi,ans[i].se); } return 0; }
E.求个前缀和,记录下最小前缀和和整个数组的和.
难点在于求会经过几个完整的回合才会遇到最终死的那个回合,这里用了倍增的方法处理,但我觉得显然可以用一个式子直接计算,只是因为我菜没想到
#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 ", x) #define Prl(x) printf("%lld ",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; LL H; LL a[maxn]; LL pre[maxn]; int main(){ Scl(H); Sca(N); LL Min = 1e18; for(int i = 1; i <= N ; i ++){ Scl(a[i]); pre[i] = pre[i - 1] + a[i]; Min = min(Min,pre[i]); } if(H + Min > 0 && pre[N] >= 0){ puts("-1"); return 0; } LL ans = 0; if(H + Min > 0){ LL x = 1; while(pre[N] * x + H + Min > 0){ x *= 2; } x /= 2; for(LL i = x; i > 0 ; i /= 2){ while(pre[N] * i + H + Min > 0){ H += pre[N] * i; ans += i * N; } } } int cnt = 0; while(H > 0){ ans++; H += a[++cnt]; if(cnt == N) cnt = 0; } Prl(ans); return 0; }
F.先求一个前缀和,很显然区间和为pre[r] - pre[l - 1],先用一个n²的操作求出所有可能的和,然后用类似邻接表的方法,以区间和为key值,区间的l,r为value值存储下来.
可以将key值hash,我这里用了map<int,pair<int,int>>Q,的方式暴力存储.
对于每个key值都寻找答案,贪心的将他们所有的区间按右端点排序就可以找到这个key值下最多的区间数目.
#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 ", x) #define Prl(x) printf("%lld ",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 = 1610; const int INF = 0x3f3f3f3f; const int mod = 1e9 + 7; int N,M,K; LL a[maxn],pre[maxn]; map<int,vector<PII>>Q; map<int,bool>P; bool cmp(PII a,PII b){ return a.se < b.se; } int main(){ Sca(N); for(int i = 1; i <= N ; i ++){ Sca(a[i]); pre[i] = pre[i - 1] + a[i]; } int ans = 0; for(int l = 1; l <= N ; l ++){ P.clear(); for(int r = l; r <= N ; r ++){ int sum = pre[r] - pre[l - 1]; if(P[sum]) continue; P[sum] = 1; Q[sum].push_back(mp(l,r)); } } map<int,vector<PII>>::iterator A; for(map<int,vector<PII>>::iterator it = Q.begin(); it != Q.end(); it++){ vector<PII>q = (*it).se; sort(q.begin(),q.end(),cmp); int t = 0; int cnt = 0; for(int i = 0 ; i < q.size(); i ++){ if(q[i].fi > t){ cnt++; t = q[i].se; } } if(ans < cnt) A = it; ans = max(ans,cnt); } Pri(ans); vector<PII>q = (*A).se; sort(q.begin(),q.end(),cmp); int t = 0; for(int i = 0 ; i < q.size(); i ++){ if(q[i].fi > t){ cout << q[i].fi << " " << q[i].se << endl; t = q[i].se; } } return 0; }
G.画画图就很显然的指导若x为公司数量ind[i] <= x的点必可以为好点,反之必为坏点.
用二分找出最小的满足坏点 <= k的公司数x,贪心的方法得到树边的染色.
#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 ", x) #define Prl(x) printf("%lld ",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 = 1610; const int INF = 0x3f3f3f3f; const int mod = 1e9 + 7; int N,M,K; LL a[maxn],pre[maxn]; map<int,vector<PII>>Q; map<int,bool>P; bool cmp(PII a,PII b){ return a.se < b.se; } int main(){ Sca(N); for(int i = 1; i <= N ; i ++){ Sca(a[i]); pre[i] = pre[i - 1] + a[i]; } int ans = 0; for(int l = 1; l <= N ; l ++){ P.clear(); for(int r = l; r <= N ; r ++){ int sum = pre[r] - pre[l - 1]; if(P[sum]) continue; P[sum] = 1; Q[sum].push_back(mp(l,r)); } } map<int,vector<PII>>::iterator A; for(map<int,vector<PII>>::iterator it = Q.begin(); it != Q.end(); it++){ vector<PII>q = (*it).se; sort(q.begin(),q.end(),cmp); int t = 0; int cnt = 0; for(int i = 0 ; i < q.size(); i ++){ if(q[i].fi > t){ cnt++; t = q[i].se; } } if(ans < cnt) A = it; ans = max(ans,cnt); } Pri(ans); vector<PII>q = (*A).se; sort(q.begin(),q.end(),cmp); int t = 0; for(int i = 0 ; i < q.size(); i ++){ if(q[i].fi > t){ cout << q[i].fi << " " << q[i].se << endl; t = q[i].se; } } return 0; }