随便拉的比赛 题解
1. HDU - 5914
意识到最贪心的保留最多饼干的方案是 1 2 3 5 8 13 21 ..... 一个斐波那契数列,任选两个筷子都成不了三角形
所以给的N每大于其中的一个数就意味着我们能多保留一个筷子,其余的都不要
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#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 = 110; const int INF = 0x3f3f3f3f; const int mod = 1e9 + 7; int N,M,K; int a[10] = {0,1,2,3,5,8,13,21}; int main(){ int T; Sca(T); int Case = 1; while(T--){ Sca(N); printf("Case #%d: ",Case++); int ans = 0; for(int i = 1; i <= 6 ; i ++){ if(N >= a[i]) ans++; } Pri(N - ans); } return 0; }
标题写着后缀数组但是并不
很显然最后一个是 > 还是 < 可以直接判断出来,然后从前往后判断,如果前一个字母比后一个大就是 > ,小就是 < ,如果相同的话就相当于两个字符串都去掉第一位比较,直接取上一个答案即可。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#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 = 1e6 + 10; const int INF = 0x3f3f3f3f; const int mod = 1e9 + 7; int N,M,K; char str[maxn]; char ans[maxn]; int main(){ int T; Sca(T); while(T--){ Sca(N); scanf("%s",str + 1); if(str[N - 1] < str[N]) ans[N - 1] = '<'; else ans[N - 1] = '>'; for(int i = N - 2; i >= 1; i --){ if(str[i] < str[i + 1]) ans[i] = '<'; else if(str[i] > str[i + 1]) ans[i] = '>'; else ans[i] = ans[i + 1]; } ans[N] = '\0'; printf("%s\n",ans + 1); } return 0; }
A串(倍增)成两倍然后KMP找B串就可以了。
1.看了下提交似乎string.find()和strstr()直接调用也能过
2.按理来说需要特判A的长度比B的长度小的情况,不然出现A(ab),B(abab)的情况会算对,不特判就过了有可能是数据水
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#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 = 100000 + 10; const int INF = 0x3f3f3f3f; const int mod = 1e9 + 7; int N,M,K; char A[maxn * 2],B[maxn]; int Next[maxn]; void kmp_pre(char x[],int m,int nxt[]){ int j = 0; nxt[1] = 0; for(int i = 2; i <= m ; i ++){ while(j && x[i] != x[j + 1]) j = nxt[j]; if(x[j + 1] == x[i]) j++; nxt[i] = j; } } bool KMP(char x[],int m,char y[],int n){ kmp_pre(x,m,Next); int j = 0; for(int i = 1; i <= n ; i ++){ while(j > 0 && x[j + 1] != y[i]) j = Next[j]; if(x[j + 1] == y[i]) j++; if(j == m) return 1; } return 0; } int main(){ while(~scanf("%s%s",A + 1,B + 1)){ int l1 = strlen(A + 1),l2 = strlen(B + 1); if(l1 < l2){ puts("no"); continue; } for(int i = l1 + 1; i <= l1 + l1; i ++){ A[i] = A[i - l1]; } if(KMP(B,l2,A,l1 + l1)) puts("yes"); else puts("no"); } return 0; }
从高位向低位扫
如果两个数字的第一位不相同,那很显然大的取10000000,小的取011111111,或一下最优秀
如果相同的话,答案的这一位就取他们相同的这个位然后继续扫
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#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 = 110; const int INF = 0x3f3f3f3f; LL l,r; int a[maxn],b[maxn],c[maxn]; int main() { int T; scanf("%d",&T); while(T--){ scanf("%lld%lld",&l,&r); if(l == r){ printf("%lld\n",l); continue; } int cnt1 = 0,cnt2 = 0; LL x = r,t = l; while(x){ a[cnt1++] = x & 1; x >>= 1; } while(t){ b[cnt2++] = t & 1; t >>= 1; } if(cnt1 > cnt2){ LL h = 1; for(int i = 0; i < cnt1; i ++){ h <<= 1; } h--; printf("%lld\n",h); }else{ int ans = 0; for(int i = cnt1 - 1; i >= 0; i --){ if(ans) c[i] = 1; else if(a[i] == 0 && b[i] == 0) c[i] = 0; else if(a[i] == 1 && b[i] == 1) c[i] = 1; else{ c[i] = 1; ans = 1; } } LL h = 1; for(int i = cnt1 - 2; i >= 0; i --){ if(c[i] == 1){ h = h * 2 + 1; }else{ h <<= 1; } } printf("%lld\n",h); //ans } } return 0; }
最暴力显然的做法是 对每个骑士搞一个完全背包
但是时间复杂度不过关 1e5 * 1e3 * 1e3
发现骑士的防御力似乎只有10?(*^_^*),那就把防御力相同的骑士放在一起,然后求10个完全背包就可以了
时间复杂度10 * 1000 * 1000
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#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 maxm = 1010; const LL INF = 1e18; const int mod = 1e9 + 7; int N,M,K; PII attack[maxm]; PII boss[maxn]; vector<int>type[20]; LL dp[maxn]; int main(){ while(~Sca2(N,M)){ int MAXb = 0,MAXa = 0; for(int i = 0; i <= 10; i ++) type[i].clear(); for(int i = 1; i <= N ; i ++){ Sca2(boss[i].fi,boss[i].se); MAXb = max(MAXb,boss[i].se); type[boss[i].se].pb(i); } for(int i = 1; i <= M; i ++){ Sca2(attack[i].fi,attack[i].se); MAXa = max(MAXa,attack[i].se); } if(MAXa <= MAXb){ puts("-1"); continue; } LL ans = 0; for(int i = 0 ; i <= 10; i ++){ for(int j = 1; j <= 1000; j ++) dp[j] = INF; dp[0] = 0; for(int j = 1; j <= M ; j ++){ int x = attack[j].se - i,p = attack[j].fi; if(x <= 0) continue; for(int k = 0 ; k <= 1000; k ++){ if(k >= x) dp[k] = min(dp[k],dp[k - x] + p); else dp[k] = min(dp[k],dp[0] + p); } } for(int j = 0 ; j < type[i].size(); j ++) ans += dp[boss[type[i][j]].fi]; } Prl(ans); } return 0; }
反正就 模拟嘛 看代码
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#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 vis[maxn]; int main(){ int T;Sca(T); while(T--){ Sca2(N,M); Mem(vis,0); LL ans = 0,num = 0; for(int i = 1; i <= M ; i ++){ int id,h,m; char op[5]; scanf("%d%d:%d%s",&id,&h,&m,op); if(op[0] == 'A' && ~vis[id]){ ans += h * 60 + m + vis[id] * 20; vis[id] = -1; num++; }else if(~vis[id]){ vis[id]++; } } printf("%lld %lld\n",num,ans); } return 0; }
nim博弈套了一个分堆
把分成三堆的SG函数求出来
发现8的倍数和+1变成8的倍数的情况有所改动,其他不变,然后就直接nim博弈
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#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 = 110; const int INF = 0x3f3f3f3f; const int mod = 1e9 + 7; int N,M,K; int main(){ int T;Sca(T); while(T--){ LL ans = 0; Sca(N); while(N--){ int x; Sca(x); if(!((x + 1) % 8)) x++; else if(!(x % 8)) x--; ans ^= x; } if(ans) puts("First player wins."); else puts("Second player wins."); } return 0; }