A.不断增加时间,直到符合要求。
#include<bits/stdc++.h> using namespace std; int a,b; char c; int f(int x) { return x%10*10+x/10; } int main() { ios::sync_with_stdio(0); cin >> a >> c >> b; int ans = 0; while(1) { if(f(a) == b) break; ans++; b++; if(b == 60) { b = 0; a++; } if(a == 24) a = 0; } cout << ans << endl; return 0; }
B.两次前缀和。
#include<bits/stdc++.h> using namespace std; int n,k,q,a[200005] = {0},ans[200005] = {0}; int main() { ios::sync_with_stdio(0); cin >> n >> k >> q; for(int i = 1;i <= n;i++) { int x,y; cin >> x >> y; a[x]++; a[y+1]--; } for(int i = 1;i <= 200000;i++) a[i] += a[i-1]; for(int i = 1;i <= 200000;i++) { ans[i] = ans[i-1]; if(a[i] >= k) ans[i]++; } while(q--) { int x,y; cin >> x >> y; cout << ans[y]-ans[x-1] << endl; } return 0; }
C.对于每一行,我们找当前最小的值,然后处理该行每一个值,每一个值减去最小值,若结果不为0,则该列处理这个值至0,最后判断是否每个点都为0。
注意n>m的时候,我们转置一下矩阵才能得到最小的答案。
#include<bits/stdc++.h> using namespace std; int n,m,a[105][105],cnt1[105] = {0},cnt2[105] = {0}; int main() { ios::sync_with_stdio(0); cin >> n >> m; int flag = 1; if(n > m) flag = 0; if(flag) { for(int i = 1;i <= n;i++) { for(int j = 1;j <= m;j++) cin >> a[i][j]; } } else { swap(n,m); for(int j = 1;j <= m;j++) { for(int i = 1;i <= n;i++) cin >> a[i][j]; } } for(int i = 1;i <= n;i++) { int minn = 1000; for(int j = 1;j <= m;j++) minn = min(minn,a[i][j]); for(int j = 1;j <= m;j++) { if(a[i][j] != minn) { int t = a[i][j]-minn; cnt2[j] += t; for(int k = 1;k <= n;k++) a[k][j] -= t; } a[i][j] -= minn; } cnt1[i] += minn; } int ok = 1; for(int i = 1;i <= n;i++) { for(int j = 1;j <= m;j++) { if(a[i][j] != 0) ok = 0; } } if(!ok) { cout << -1 << endl; return 0; } int ans = 0; for(int i = 1;i <= n;i++) ans += cnt1[i]; for(int i = 1;i <= m;i++) ans += cnt2[i]; cout << ans << endl; if(flag) { for(int i = 1;i <= n;i++) { while(cnt1[i]) { cnt1[i]--; cout << "row " << i << endl; } } for(int i = 1;i <= m;i++) { while(cnt2[i]) { cnt2[i]--; cout << "col " << i << endl; } } } else { for(int i = 1;i <= n;i++) { while(cnt1[i]) { cnt1[i]--; cout << "col " << i << endl; } } for(int i = 1;i <= m;i++) { while(cnt2[i]) { cnt2[i]--; cout << "row " << i << endl; } } } return 0; }
D.发现n是偶数的时候,会有规律,每隔两行会是前面的两个数相加,直接计算二项式的系数,最后一步的加减取决于n%4。
如果n是奇数,先模拟一行变成偶数。
#include<bits/stdc++.h> #define MOD 1000000007 using namespace std; int n,a[200005]; long long fac[100005] = {1}; long long qpow(long long a,long long b) { long long ans = 1; while(b) { if(b%2) ans = ans*a%MOD; a = a*a%MOD; b /= 2; } return ans; } int main() { ios::sync_with_stdio(0); for(int i = 1;i <= 100000;i++) fac[i] = fac[i-1]*i%MOD; cin >> n; for(int i = 0;i < n;i++) cin >> a[i]; if(n == 1) { cout << a[0] << endl; return 0; } if(n%2) { n--; int now = 1; for(int i = 0; i < n;i++) { if(now) a[i] = (a[i]+a[i+1])%MOD; else a[i] = (a[i]-a[i+1]+MOD)%MOD; now ^= 1; } } n = n/2-1; long long ans1 = 0,ans2 = 0; for(int i = 0;i <= n;i++) { long long t = fac[n]*qpow(fac[i]*fac[n-i]%MOD,MOD-2)%MOD; ans1 = (ans1+t*a[i*2]%MOD)%MOD; ans2 = (ans2+t*a[i*2+1]%MOD)%MOD; } if(n%2) cout << (ans1-ans2+MOD)%MOD << endl; else cout << (ans1+ans2)%MOD << endl; return 0; }
E.树形DP,dp[i][j][k]代表(当前在i点,买了j个商品,是否购买当前商品)的最少花费。
#include<bits/stdc++.h> #define MOD 1000000007 using namespace std; int n,m,a[5005],b[5005],sz[5005] = {0},ok[5005] = {0}; long long dp[5005][5005][2]; vector<int> v[5005]; void dfs(int now) { if(ok[now]) return; dp[now][0][0] = 0; dp[now][1][0] = a[now]; dp[now][1][1] = b[now]; sz[now] = 1; for(int i = 0;i < v[now].size();i++) { int t = v[now][i]; dfs(t); for(int i = sz[now];i >= 0;i--) { for(int j = sz[t];j >= 0;j--) { dp[now][i+j][0] = min(dp[now][i+j][0],dp[now][i][0]+dp[t][j][0]); dp[now][i+j][1] = min(dp[now][i+j][1],dp[now][i][1]+min(dp[t][j][0],dp[t][j][1])); } } sz[now] += sz[t]; } ok[now] = 1; } int main() { ios::sync_with_stdio(0); cin >> n >> m; for(int i = 1;i <= n;i++) { cin >> a[i] >> b[i]; b[i] = a[i]-b[i]; if(i > 1) { int x; cin >> x; v[x].push_back(i); } } memset(dp,0x3f,sizeof(dp)); dfs(1); for(int i = n;i >= 0;i--) { if(dp[1][i][0] <= m || dp[1][i][1] <= m) { cout << i << endl; return 0; } } return 0; }