Problem A
题意:二维平面中有一个地球E和一个二向箔V,V每次绕自己扩展一圈,求多少次后到达地球。
题解:输出E和V横坐标差与纵坐标差中最大的即可。
代码:
1 #include<bits/stdc++.h> 2 #define int long long 3 using namespace std; 4 5 int T; 6 int n, m; 7 signed main() { 8 int a, b, c, d; 9 cin>>n>>m; 10 for(int i = 1;i<=n;++i) { 11 for(int j = 1; j<=m;++j){ 12 char s; 13 cin>>s; 14 if(s == 'E') { 15 a = i; 16 b = j; 17 } 18 if( s== 'V') { 19 c = i; 20 d= j; 21 } 22 } 23 } 24 int l = abs(a-c); 25 int r = abs(b-d); 26 int ans = max(l,r); 27 cout<<ans; 28 return 0; 29 }
Problem B
题意:储藏仓初始位置为0,初始能量为0,每一点能量能使储藏仓移动距离1。有n个核弹,第i个核弹在坐标为xi的位置,有vi的推动力。如果储藏仓经过xi,那么该位置核弹会给储藏仓增加vi点能量值。Q次询问,每次询问一个正整数k,询问储藏仓能否移动到坐标为k的位置。输入保证xi递增,第一个核弹在位置0。
题解:记录ans为当前能到达的最远距离,输入核弹的x和v时,若x<=ans,那么ans+=v。询问时,判断k是否小于等于ans即可。
代码:
1 #include<bits/stdc++.h> 2 #define int long long 3 using namespace std; 4 const int maxn = 1e5+1000; 5 int T; 6 int n, m; 7 signed main() { 8 cin>>n; 9 int ans = 0; 10 for(int i = 1, p, v; i <= n; ++i) { 11 scanf("%lld%lld", &p, &v); 12 if(p<=ans) ans+=v; 13 } 14 cin>>m; 15 for(int i = 1; i <= m; ++i) { 16 int query; 17 scanf("%lld" ,&query); 18 if(query<= ans) printf("Yes\n"); 19 else printf("No\n"); 20 } 21 return 0; 22 }
Problem C
题意:两群人分别有n个人和m个人。现有两个智子,每个智子监控其中一群人,但一共只能监控p个人。求方案数。(对13331取模)
题解:用两层循环,i、j,分别表示从第一群人中选i个人,第二群人中选j个人,要保证i+j小于等于p,然后用组合数求方案数。最后要减1,即减去选了0个人方案。组合数用递推公式预处理即可。
1 #include<bits/stdc++.h> 2 #define int long long 3 using namespace std; 4 const int mod = 13331; 5 int T; 6 int n, m, p; 7 int C[1010][1010]; 8 signed main() { 9 cin>>n>>m>>p; 10 C[0][0] = 1; 11 for(int i = 1; i<= 1000;++i) 12 for(int j = 0;j<=1000;++j) 13 if(j == 0) C[i][j] = 1; 14 else C[i][j] = C[i-1][j]+C[i-1][j-1]%mod; 15 int ans = 0; 16 for(int i = 0; i <= min(p,n); ++i) { 17 for(int j = 0; j<=min(p-i,m);++j) { 18 ans += C[n][i]*C[m][j]%mod; 19 } 20 } 21 ans--; 22 ans = (ans+mod)%mod; 23 cout<<ans; 24 return 0; 25 }
Problem D
题意:在Problem C的基础上,有k(k <= 1e5)个智子来监控k群人,第i群人有ai个人(Σai <= 1e6)。一共只能监控p个人,求方案数。(对998244353取模)
题解:设总人数为sum。因为每个人都是独立不重复的,那么答案就是C(sum, 1)+C(sum, 2)+C(sum, 3)+.....(It's just a joke)
代码:
1 #include<bits/stdc++.h> 2 #define int long long 3 using namespace std; 4 const int mod = 998244353; 5 const int maxn = 1e6+100; 6 int T; 7 int n, m, p, k, ans; 8 int f[maxn], inv[maxn]; 9 int sum; 10 int ksm(int a, int b){ 11 int ans = 1; 12 while(b) { 13 if(b&1) ans=(ans*a)%mod; 14 a = a * a%mod; 15 b>>=1; 16 } 17 return ans; 18 } 19 int C(int sum,int to) { 20 f[0] = 1; 21 for(int i = 1 ;i<=sum;++i) f[i] = i*f[i-1]%mod; 22 inv[sum] = ksm(f[sum], mod-2); 23 for(int i = sum - 1; i >= 0; --i) inv[ i ] = inv[i+1] * (i + 1) % mod; 24 for(int i = 1;i<=to;++i) { 25 ans = (ans+f[sum]*inv[i]%mod*inv[sum-i])%mod; 26 } 27 return ans; 28 } 29 signed main() { 30 cin>>k; 31 for(int i = 1; i<=k;++i){ 32 int a; 33 scanf("%lld", &a); 34 sum +=a; 35 } 36 cin>>p; 37 cout<<C(sum, min(sum, p)); 38 return 0; 39 }
Problem E
题意:游戏赢一局得1分,输一局得-1分。连赢三局时,赢一局得2分。赢一局得概率是a / b。k (k <= 1000)次询问,每次询问求 n (n <= 1e9)局后期望得分(对19260817取模)。
题解:找规律。设赢一局概率p。n = 1时,期望得分是2*p-1。n = 2时,期望得分是4*p-2。n = 3时,期望得分是p*p*p +6*p - 3。n = 4时,期望得分是2*p*p*p +8*p - 4。那么猜测答案是(n-2)*p*p*p +n(2p - 1)。打表发现确实是这样(我这个憨憨最开始式子推错了,所以是嗯打表找出来的规律)。
代码:
1 #include<bits/stdc++.h> 2 #define int long long 3 using namespace std; 4 const int mod = 19260817; 5 int T; 6 int ans; 7 int n, a, b; 8 int inv,win; 9 int ksm(int a, int b){ 10 int ans = 1; 11 while(b) { 12 if(b&1) ans=(ans*a)%mod; 13 a = a * a%mod; 14 b>>=1; 15 } 16 return ans; 17 } 18 signed main() { 19 cin>>T; 20 while(T--) { 21 ans = 0; 22 scanf("%lld%lld%lld", &n, &a, &b); 23 inv = ksm(b, mod-2); 24 win = a * inv % mod; 25 if(n == 1) ans = (2 * win - 1)%mod; 26 else if(n == 2) ans = (4*win - 2)%mod; 27 else { 28 int base = (win*win%mod*win%mod)%mod; 29 ans = (base * (n-2))%mod; 30 ans = (ans+ n * (2*win - 1)%mod)%mod; 31 } 32 printf("%lld\n", ans); 33 } 34 return 0; 35 }
Problem F
题意:把一些数字的所有因数写在纸上,每张纸写一个因数,一共n (n <= 5000) 张纸。求出原来的那些数字。
题解:可以发现1的个数就是原来的数字的个数(虽然没什么用)。把所有因数从大到小排序,每取一个数,暴力往下删除它的所有因数。
代码:
1 #include<bits/stdc++.h> 2 #define int long long 3 using namespace std; 4 5 int T; 6 int n, m; 7 int a[50500],ans[50050],vis[50050]; 8 int sum; 9 int cnt; 10 signed main() { 11 cin>>n; 12 for(int i = 1; i<=n;++i) 13 scanf("%lld", &a[i]); 14 sort(a+1, a+1+n); 15 int qwq = 0; 16 for(int i = n; i>=1; --i){ 17 if(!vis[i]){ 18 int last = 0; 19 ans[++qwq] = a[i]; 20 for(int j = 1; j < i; ++j){ 21 if(a[j]!=last && !vis[j] && a[i]%a[j] == 0&& a[i]!=a[j]){ 22 last = a[j]; 23 vis[j] = 1; 24 } 25 } 26 } 27 } 28 sort(ans+1, ans+1+qwq); 29 cout<<qwq<<endl; 30 for(int i = 1; i <= qwq; ++i) 31 printf("%lld ", ans[i]); 32 return 0; 33 }