Problem L. Graph Theory Homework
思路:很容易想到一步从 1 走到 n 最优。
#include<bits/stdc++.h> #define LL long long #define fi first #define se second #define mk make_pair #define pii pair<int,int> #define piii pair<int, pair<int,int>> using namespace std; const int N = 2e5 + 7; const int M = 1e4 + 7; const int inf = 0x3f3f3f3f; const LL INF = 0x3f3f3f3f3f3f3f3f; const int mod = 1e9 + 7; const double eps = 1e-10; const double PI = acos(-1); int n, a[N]; int main() { int T; scanf("%d", &T); while(T--) { scanf("%d", &n); for(int i = 1; i <= n; i++) scanf("%d", &a[i]); printf("%d ", (int)sqrt(abs(a[n] - a[1]))); } return 0; } /* */
Problem K. Expression in Memories
思路:把0的情况搞清楚就好啦。
#include<bits/stdc++.h> #define LL long long #define fi first #define se second #define mk make_pair #define pii pair<int,int> #define piii pair<int, pair<int,int>> using namespace std; const int N = 2e5 + 7; const int M = 1e4 + 7; const int inf = 0x3f3f3f3f; const LL INF = 0x3f3f3f3f3f3f3f3f; const int mod = 1e9 + 7; const double eps = 1e-10; const double PI = acos(-1); char s[N]; int n; bool is(char c) { if(c == '+' || c == '*') return true; return false; } int main() { int T; scanf("%d", &T); while(T--) { scanf("%s", s + 1); n = strlen(s + 1); s[0] = '+'; bool flag = true; for(int i = 2; i <= n; i++) { if(is(s[i]) && is(s[i - 1])) { flag = false; break; } } if(is(s[1]) || is(s[n])) flag = false; if(!flag) { puts("IMPOSSIBLE"); continue; } for(int i = 1; i <= n && flag; i++) { if(s[i] == '0') { if(s[i - 1] >= '0' && s[i - 1] <= '9') continue; else if(is(s[i - 1])) { if(i < n) { if(!is(s[i + 1])) { if(s[i + 1] == '?') s[i + 1] = '+'; else { flag = false; break; } } } } else { s[i - 1] = '1'; } } } for(int i = 1; i <= n; i++) { if(s[i] == '?') s[i] = '1'; } for(int i = 2; i <= n; i++) { if(is(s[i]) && is(s[i - 1])) { flag = false; break; } } for(int i = 1; i < n; i++) { if(s[i] == '0' && is(s[i - 1])) { if(s[i + 1] >= '0' && s[i + 1] <= '9') { flag = false; break; } } } if(is(s[1]) || is(s[n])) flag = false; if(!flag) puts("IMPOSSIBLE"); else puts(s + 1); } return 0; } /* */
Problem E. Matrix from Arrays
思路:打表找规律发现,n为奇数的时候n * n的矩阵循环,n为偶数时2n * 2n的矩阵循环,然后就二维前缀和搞一搞。
题目没有取模我傻傻地加了取模WA了一次。。
#include<bits/stdc++.h> #define LL long long using namespace std; const int N = 100 + 7; const int mod = 1e9 + 7; LL M[N][N], dp[N][N]; LL A[N]; int n; LL sum; void init() { int cursor = 0; for (int i = 0; i <= 100; ++i) { for (int j = 0; j <= i; ++j) { M[j][i - j] = A[cursor]; cursor = (cursor + 1) % n; } } } LL cal(LL x, LL y) { LL cnt1 = x / n, cnt2 = y / n; LL ans = sum * cnt1 * cnt2; LL num1 = x % n, num2 = y % n; ans += dp[num1][num2]; ans += dp[num1][n - 1] * cnt2; ans += dp[n - 1][num2] * cnt1; return ans; } int main(){ int T; scanf("%d", &T); while(T--) { scanf("%d",&n); memset(dp, 0, sizeof(dp)); memset(M, 0, sizeof(M)); sum = 0; for(int i = 0; i < n; i++) scanf("%d", &A[i]); init(); if(n % 2 == 0) n <<= 1; for(int i = 0; i < n; i++) { for(int j = 0; j < n; j++) { sum += M[i][j]; dp[i][j] += M[i][j]; if(i) dp[i][j] += dp[i - 1][j]; if(j) dp[i][j] += dp[i][j - 1]; if(i && j) dp[i][j] -= dp[i - 1][j - 1]; } } int q; scanf("%d", &q); while(q--) { LL x0, y0, x1, y1, ans = 0; scanf("%lld%lld%lld%lld", &x0, &y0, &x1, &y1); ans = cal(x1, y1); if(x0 && y0) ans += cal(x0 - 1, y0 - 1); if(x0) ans -= cal(x0 - 1, y1); if(y0) ans -= cal(x1, y0 - 1); printf("%lld ", ans); } } return 0; } /* */
Problem D. Nothing is Impossible
思路:这个题无力吐槽,题面改了又改。。 居然还有那么多人用错的题面过了题。。。
#include<bits/stdc++.h> #define LL long long using namespace std; const int N = 100 + 7; const int mod = 1e9 + 7; LL n, m, b[N]; int main(){ int T; scanf("%d", &T); while(T--) { scanf("%lld%lld", &n, &m); for(int i = 1; i <= n; i++) { LL a; scanf("%lld%lld", &a, &b[i]); } LL now = 1, ans = 0; sort(b + 1, b + 1 + n); for(int i = 1; i <= n; i++) { now *= (b[i] + 1); if(now > m) break; ans = i; } printf("%lld ", ans); } return 0; } /* */
Problem J. Let Sudoku Rotate
思路:暴力dfs然后剪枝
#include<bits/stdc++.h> using namespace std; bool did[2][16][16]; char s[20][20]; struct pos{ int xx,yy,v; }; vector<pos> v[5][5][16]; int ans; void Get(int x,int y, int w) { char c; if(w <= 9) c = w + '0'; else c = 'A' + (w - 10); int xx=x/4; int yy=y/4; int i,j; bool judge=false; for(i=x;i<x+4;i++){ for(j=y;j<y+4;j++){ if(s[i][j]==c){ judge=true; break; } } if(judge) break; } v[xx][yy][w].push_back({i,j,0}); if(i%4==0&&j%4==0){ v[xx][yy][w].push_back({i,j+3,1}); v[xx][yy][w].push_back({i+3,j+3,2}); v[xx][yy][w].push_back({i+3,j,3}); } else if(i%4==0&&j%4==3){ v[xx][yy][w].push_back({i+3,j,1}); v[xx][yy][w].push_back({i+3,j-3,2}); v[xx][yy][w].push_back({i,j-3,3}); } else if(i%4==3&&j%4==0){ v[xx][yy][w].push_back({i-3,j,1}); v[xx][yy][w].push_back({i-3,j+3,2}); v[xx][yy][w].push_back({i,j+3,3}); } else if(i%4==3&&j%4==3){ v[xx][yy][w].push_back({i,j-3,1}); v[xx][yy][w].push_back({i-3,j-3,2}); v[xx][yy][w].push_back({i-3,j,3}); } //// else if(i%4==1&&j%4==0){ v[xx][yy][w].push_back({i-1,j+2,1}); v[xx][yy][w].push_back({i+1,j+3,2}); v[xx][yy][w].push_back({i+2,j+1,3}); } else if(i%4==3&&j%4==1){ v[xx][yy][w].push_back({i-2,j-1,1}); v[xx][yy][w].push_back({i-3,j+1,2}); v[xx][yy][w].push_back({i-1,j+2,3}); } else if(i%4==2&&j%4==3){ v[xx][yy][w].push_back({i+1,j-2,1}); v[xx][yy][w].push_back({i-1,j-3,2}); v[xx][yy][w].push_back({i-2,j-1,3}); } else if(i%4==0&&j%4==2){ v[xx][yy][w].push_back({i+2,j+1,1}); v[xx][yy][w].push_back({i+3,j-1,2}); v[xx][yy][w].push_back({i+1,j-2,3}); } // else if(i%4==2&&j%4==0){ v[xx][yy][w].push_back({i-2,j+1,1}); v[xx][yy][w].push_back({i-1,j+3,2}); v[xx][yy][w].push_back({i+1,j+2,3}); } else if(i%4==3&&j%4==2){ v[xx][yy][w].push_back({i-1,j-2,1}); v[xx][yy][w].push_back({i-3,j-1,2}); v[xx][yy][w].push_back({i-2,j+1,3}); } else if(i%4==1&&j%4==3){ v[xx][yy][w].push_back({i+2,j-1,1}); v[xx][yy][w].push_back({i+1,j-3,2}); v[xx][yy][w].push_back({i-1,j-2,3}); } else if(i%4==0&&j%4==1){ v[xx][yy][w].push_back({i+1,j+2,1}); v[xx][yy][w].push_back({i+3,j+1,2}); v[xx][yy][w].push_back({i+2,j-1,3}); } //// else if(i%4==1&&j%4==1){ v[xx][yy][w].push_back({i,j+1,1}); v[xx][yy][w].push_back({i+1,j+1,2}); v[xx][yy][w].push_back({i+1,j,3}); } else if(i%4==1&&j%4==2){ v[xx][yy][w].push_back({i+1,j,1}); v[xx][yy][w].push_back({i+1,j-1,2}); v[xx][yy][w].push_back({i,j-1,3}); } else if(i%4==2&&j%4==1){ v[xx][yy][w].push_back({i-1,j,1}); v[xx][yy][w].push_back({i-1,j+1,2}); v[xx][yy][w].push_back({i,j+1,3}); } else if(i%4==2&&j%4==2){ v[xx][yy][w].push_back({i,j-1,1}); v[xx][yy][w].push_back({i-1,j-1,2}); v[xx][yy][w].push_back({i-1,j,3}); } } void dfs(int x,int y,int step){ if(step>=ans) return ; if(x==4){ ans=min(ans,step); return ; } for(int i=0;i<4;i++) { bool flag = true; for(int w = 0; w < 16; w++) { int tx=v[x][y][w][i].xx,ty=v[x][y][w][i].yy; if(did[0][tx][w]||did[1][ty][w]) flag=false; } //printf("%d %d ",tx,ty); if(flag){ for(int w=0;w<16;w++){ int tx=v[x][y][w][i].xx,ty=v[x][y][w][i].yy; did[0][tx][w]=true; did[1][ty][w]=true; } if(y==3){ dfs(x+1,0,step+v[x][y][0][i].v); } else{ dfs(x,y+1,step+v[x][y][0][i].v); } for(int w=0;w<16;w++){ int tx=v[x][y][w][i].xx,ty=v[x][y][w][i].yy; did[0][tx][w]=false; did[1][ty][w]=false; } } } } int main(){ int T; scanf("%d",&T); while(T--){ memset(did,false,sizeof(did)); for(int i=0;i<16;i++) scanf("%s",s[i]); for(int i=0;i<4;i++) for(int j=0;j<4;j++) for(int w = 0; w < 16; w++) v[i][j][w].clear(); for(int i=0;i<16;i+=4) { for(int j=0;j<16;j+=4) { for(int k = 0; k < 16; k++) Get(i, j, k); } } ans=1000000; dfs(0,0,0); printf("%d ",ans); } }
补题****************************************************************
Problem B. Harvest of Apples
思路:这个莫队真的不好想,首先得推出公式来。。。
S(n, m + 1) = S(n, m) + C(n, m + 1)
S(n + 1, m) = 2 * S(n, m) - C(n, m)
然后搞莫队。。
#include<bits/stdc++.h> #define LL long long #define fi first #define se second #define mk make_pair #define pii pair<int,int> #define pLL pair<long long, long long> #define piii pair<int, pair<int,int>> using namespace std; const int N = 1e5 + 7; const int M = 1e4 + 7; const int inf = 0x3f3f3f3f; const LL INF = 0x3f3f3f3f3f3f3f3f; const int mod = 1e9 + 7; const double eps = 1e-10; const double PI = acos(-1); const int B = 300; int ans[N], f[N], inv[N]; LL ret; struct Qus { int n, m, id; bool operator < (const Qus &rhs) const { if(n / B == rhs.n / B) return m < rhs.m; return n / B < rhs.n / B; } } qus[N]; int fastPow(int a, int b) { int ans = 1; while(b) { if(b & 1) ans = 1ll * ans * a % mod; a = 1ll * a * a % mod; b >>= 1; } return ans; } void init() { f[0] = 1; for(int i = 1; i < N; i++) f[i] = 1ll * f[i - 1] * i % mod; inv[N - 1] = fastPow(f[N - 1], mod - 2); for(int i = N - 2; i >= 0; i--) inv[i] = 1ll * inv[i + 1] * (i + 1) % mod; } int comb(int n, int m) { return 1ll * f[n] * inv[m] % mod * inv[n - m] % mod; } void update1(int m, int n, int op) { op = -op; ret += op * comb(n, m + 1); if(ret >= mod) ret -= mod; if(ret < 0) ret += mod; } void update2(int m, int n, int op) { if(op == 1) { ret += ret; if(ret >= mod) ret -= mod; ret -= comb(n - 1, m); if(ret < 0) ret += mod; } else { ret += comb(n - 1, m); if(ret >= mod) ret -= mod; ret = ret * inv[2] % mod; } } int main() { init(); int q; scanf("%d", &q); for(int i = 1; i <= q; i++) { scanf("%d%d", &qus[i].n, &qus[i].m); qus[i].id = i; } sort(qus + 1, qus + q + 1); ret = 1; int l = 0, r = 1; for(int i = 1; i <= q; i++) { int L = qus[i].m, R = qus[i].n; while(r < R) update2(l, ++r, 1); while(l > L) update1(--l, r, 1); while(r > R) update2(l, r--, -1); while(l < L) update1(l++, r, -1); ans[qus[i].id] = ret; } for(int i = 1; i <= q; i++) printf("%d ", ans[i]); return 0; } /* */