浙江农林大学第十九届程序设计竞赛暨天梯赛选拔赛(同步赛)
D-涛涛和策策的游戏:博弈论(sg)
思路:游戏输的一方是找不到一个大于1的数,那么就是说每个人都想最先让所有数变为1。所有如果双方都会考虑让对方把这个数变成素数,所以我们就去找每个数有多少个素因子,这就类似于尼姆游戏了,每个数相当于每堆石子,素因子个数相当于每堆石子的个数,然后异或一下便可得到答案。
#include <iostream> #include <cstdio> #include <algorithm> #include <time.h> #include <stack> #include <queue> #include <string.h> #include <cmath> #include <bitset> #include <set> #include <map> #define ll long long const int inf = 0x3f3f3f3f; const int mod = 1e9+7; const ll ds = 1e15+7; const double p = 3.141592653589793238462643383; using namespace std; ll zhi(int x) { ll cnt = 0; for(int i = 2; i <= sqrt(x); i++){ if(x % i == 0){ while(x % i == 0){ cnt++; x /= i; } } } if(x > 1) cnt++; return cnt; } int main() { int n,x; scanf("%d",&n); ll ans = 0; for(int i = 1; i <= n; i++){ scanf("%d",&x); ans ^= zhi(x); } if(ans == 0) printf("TT txdy!"); else printf("CC yyds!"); return 0; }
F-学长的白日梦:快速幂
python处理大数
mod = 9999999967 def f(a,b): res = 1 while(b != 0): if(b & 1): res = (res*a) % mod b = b >> 1 a = (a*a)%mod return res%mod t = int(input()) while t != 0: a,b = map(int,input().split()) print(f(a,b)%mod) t = t - 1
k-dousha篮球时间
注意题目给的01串就是初始串。
#include <iostream> #include <cstdio> #include <algorithm> #include <time.h> #include <stack> #include <queue> #include <string.h> #include <cmath> #include <bitset> #include <set> #include <map> #define ll long long const int inf = 0x3f3f3f3f; const int mod = 1e9+7; const ll ds = 1e15+7; const double p = 3.141592653589793238462643383; using namespace std; int main() { int n,q; char s[1000005]; scanf("%d%d",&n,&q); scanf("%s",s+1); int ans = 0; s[0] = '0'; s[n+1] = '0'; for(int i = 1; i <= n; i++){ if(s[i] == '1' && s[i - 1] == '0') ans++; } printf("%d\n",ans); int x; for(int i = 1; i <= q; i++){ scanf("%d",&x); if(s[x] == '0'){ s[x] = '1'; if(s[x-1] == '0' && s[x+1] == '0'){ ans++; } else if(s[x-1] == '1' && s[x+1] == '1'){ ans--; } printf("%d\n",ans); } else{ s[x] = '0'; if(s[x-1] == '1' && s[x+1] == '1') ans++; else if(s[x-1] == '0' && s[x+1] == '0') ans--; printf("%d\n",ans); } } return 0; }
M-灾难预警:bfs+二分
思路:先二分出不能通过的最高水位,然后判断当前水位是否超过这个临界点。
#include <iostream> #include <cstdio> #include <algorithm> #include <time.h> #include <stack> #include <queue> #include <string.h> #include <cmath> #include <bitset> #include <set> #include <map> #define ll long long const int inf = 0x3f3f3f3f; const int mod = 1e9+7; const ll ds = 1e15+7; const double p = 3.141592653589793238462643383; using namespace std; struct node{ int x,y; node(int a,int b){ x = a; y = b; } }; int a[1005][1005]; int dp[100005]; int vis[1005][1005]; int dir[4][2] = {{1,0},{-1,0},{0,1},{0,-1}}; int n,q,h; bool check(int x,int y) { if(x <= 0 || x > n || y <= 0 || y > n) return false; return true; } bool bfs(int k) { memset(vis,0,sizeof(vis)); queue<node>d; if(a[1][1] < k) { return false; } d.push(node(1,1)); while(!d.empty()){ node s = d.front(); d.pop(); if(s.x == n && s.y == n){ return true; } int x,y; for(int i = 0; i < 4; i++){ x = s.x + dir[i][0]; y = s.y + dir[i][1]; if(check(x,y) && !vis[x][y] && a[x][y] >= k){ d.push(node(x,y)); vis[x][y] = 1; } } } return false; } int main() { scanf("%d",&n); for(int i = 1; i <= n; i++) for(int j = 1; j <= n; j++) scanf("%d",&a[i][j]); int l = 0,r = 100001,ans = 0; while(l <= r){ int mid = (l + r) >> 1; // cout << mid<< endl; if(bfs(mid)){ l = mid+1; ans = mid; } else r = mid - 1; } scanf("%d",&q); // cout << ans << endl; while(q--){ scanf("%d",&h); if(h > ans) printf("Hmmm\n"); else printf("Wuhu\n"); } return 0; }