主要是卡了一下 接下来2题还在做 都有思路
1001
考虑全然即可了
#include <cstdio> #include <cstring> using namespace std; int main() { int T; scanf("%d", &T); while(T--) { __int64 n, m, v, k; scanf("%I64d %I64d %I64d %I64d", &n, &m, &v, &k); if(m >= n) { puts("0"); continue; } if(k <= 1 || m <= v || (m-v)*k == m) { puts("-1"); continue; } int sum = 0; while(m < n && m >= 0) { sum++; m = (m-v)*k; } if(m <= 0 && m < n) sum = -1; printf("%d\n", sum); } return 0; }
1002
1003
这题错了半天 伤不起 转成字符串搞字典树就错 最后直接位运算&建树就对了
AC代码
#include <cstdio> #include <cstring> typedef __int64 LL; const int maxn = 100010; const int maxnode = 60000000; const int sigma_size = 2; LL a[maxn]; char s[maxn][70]; int ch[maxnode][sigma_size]; LL val[maxnode]; int sz; void init() { sz = 1; memset(ch[0], 0, sizeof(ch[0])); } void insert(LL v) { int u = 0; for(int i = 31; i >= 0; i--) { int c = (v&(1<<i)) == 0 ? 0 : 1; if(!ch[u][c]) { memset(ch[sz], 0, sizeof(ch[sz])); ch[u][c] = sz++; } u = ch[u][c]; } val[u] = v; } void find(LL x) { LL ans = 0; int u = 0; for(int i = 31; i >= 0; i--) { int c = (x&(1<<i)) == 0 ? 0 : 1; if(ch[u][c^1]) u = ch[u][c^1]; else u = ch[u][c]; } printf("%I64d\n", val[u]); } int main() { int cas = 1; int T; scanf("%d", &T); while(T--) { init(); int n, m; scanf("%d %d", &n, &m); for(int i = 1; i <= n; i++) { scanf("%I64d", &a[i]); insert(a[i]); } printf("Case #%d:\n", cas++); while(m--) { LL x; scanf("%I64d", &x); find(x); } } return 0; }
然后是错误代码
#include <cstdio> #include <cstring> const int maxn = 100010; const int maxnode = 10000000; const int sigma_size = 2; __int64 a[maxn]; char s[maxn][70]; int ch[maxnode][sigma_size]; int val[maxnode]; int sz; void init() { sz = 1; memset(ch[0], 0, sizeof(ch[0])); } void insert(char *s, __int64 x) { int u = 0, n = 60; for(int i = 0; i < 35; i++) { int c = s[i] - '0'; if(!ch[u][c]) { memset(ch[sz], 0, sizeof(ch[sz])); val[sz] = 0; ch[u][c] = sz++; } u = ch[u][c]; } val[u] = x; } void find(char *s) { __int64 ans = 0; int u = 0, n = 35; for(int i = 0; i < 35; i++) { int c = s[i] - '0'; if(ch[u][c^1]) { u = ch[u][c^1]; } else { u = ch[u][c]; } } printf("%I64d\n", val[u]); } int main() { int cas = 1; int T; scanf("%d", &T); while(T--) { init(); int n, m; scanf("%d %d", &n, &m); for(int i = 1; i <= n; i++) { scanf("%I64d", &a[i]); int x = 35; __int64 y = a[i]; s[i][x] = 0; while(x--) { s[i][x] = y % 2 + '0'; y /= 2; } insert(s[i], a[i]); //puts(s[i]); } printf("Case #%d:\n", cas++); while(m--) { __int64 y; char str[60]; scanf("%I64d", &y); int x = 35; str[x] = 0; while(x--) { str[x] = y % 2 + '0'; y /= 2; } //puts(str); find(str); } } return 0; }
1004
简单递推一下
每个点能够由它左边过来然后在从这个点向上向下跟新最大值
#include <cstdio> #include <cstring> #include <algorithm> using namespace std; const int maxn = 110; const int INF = 9999999; int dp[maxn][maxn]; int a[maxn][maxn]; bool vis[maxn][maxn][3]; int main() { int cas = 1; int T; scanf("%d", &T); while(T--) { int n, m; scanf("%d %d", &n, &m); for(int i = 1; i <= n; i++) for(int j = 0; j <= m; j++) dp[i][j] = -INF; for(int i = 1; i <= n; i++) for(int j = 1; j <= m; j++) scanf("%d", &a[i][j]); dp[1][1] = a[1][1]; memset(vis, false, sizeof(vis)); for(int i = 2; i <= n; i++) dp[i][1] = dp[i-1][1] + a[i][1]; for(int i = 1; i < m; i++) { for(int j = 1; j <= n; j++) { int temp = dp[j][i] + a[j][i+1]; dp[j][i+1] = max(dp[j][i+1], temp); int temp1 = temp; for(int k = j-1; k >= 1; k--) { temp1 += a[k][i+1]; dp[k][i+1] = max(dp[k][i+1], temp1); } int temp2 = temp; for(int k = j+1; k <= n; k++) { temp2 += a[k][i+1]; dp[k][i+1] = max(dp[k][i+1], temp2); } } } printf("Case #%d:\n", cas++); printf("%d\n", dp[1][m]); } return 0; }