XDOJ
1000.a+b。
#include<bits/stdc++.h> using namespace std; int a,b; int main() { ios::sync_with_stdio(false); while(~scanf("%d%d",&a,&b)) printf("%d\n",a+b); return 0; }
1001.不知道n和m大小,可以用一维数组处理位置,或者直接使用vector。
#include<bits/stdc++.h> using namespace std; int n,m,q,a[1000005],r[1000005],c[1000005]; string s; int main() { ios::sync_with_stdio(false); int z = 0; while(cin >> n >> m) { cout << "Case #" << ++z << ":" << endl; for(int i = 1;i <= n;i++) r[i] = i; for(int i = 1;i <= m;i++) c[i] = i; int cnt = 0; for(int i = 1;i <= n;i++) { cin >> s; for(int j = 0;j < m;j++) { if(s[j] == 'T') a[++cnt] = 1; else if(s[j] == 'i') a[++cnt] = 2; else a[++cnt] = 0; } } cin >> q; while(q--) { int x,y,z; cin >> x >> y >>z; if(x == 1) { int t = (r[y]-1)*m+c[z]; switch(a[t]) { case 0: cout << "Empty" << endl;break; case 1: cout << "Tree" << endl;break; case 2: cout << "Phone" << endl;break; } } else if(x == 2) swap(r[y],r[z]); else swap(c[y],c[z]); } } return 0; }
#include<bits/stdc++.h> using namespace std; int n,m,q,r[1000005],c[1000005]; vector<int> v[1000005]; string s; int main() { ios::sync_with_stdio(false); int z = 0; while(cin >> n >> m) { cout << "Case #" << ++z << ":" << endl; for(int i = 1;i <= n;i++) r[i] = i; for(int i = 1;i <= m;i++) c[i] = i; for(int i = 1;i <= n;i++) { v[i].clear(); v[i].push_back(0); } for(int i = 1;i <= n;i++) { cin >> s; for(int j = 0;j < m;j++) { if(s[j] == 'T') v[i].push_back(1); else if(s[j] == 'i') v[i].push_back(2); else v[i].push_back(0); } } cin >> q; while(q--) { int x,y,z; cin >> x >> y >>z; if(x == 1) { switch(v[r[y]][c[z]]) { case 0: cout << "Empty" << endl;break; case 1: cout << "Tree" << endl;break; case 2: cout << "Phone" << endl;break; } } else if(x == 2) swap(r[y],r[z]); else swap(c[y],c[z]); } } return 0; }
1002.dp[x][y][z]代表前x段,y个绿,z个蓝造成的最大伤害,复杂度O(n^3)。
可以优化空间,优化到二维状态。
继续优化时间,可以贪心发现红放最末为最优,于是一开始全放红,dp[x][y]表示x个绿,y个蓝的最大伤害,复杂度O(n^2)。
#include<bits/stdc++.h> #define LL long long using namespace std; LL n,x,y,z,t; LL dp[105][105][105]; int main() { while(cin >> n) { cin >> x >> y >> z >> t; memset(dp,0,sizeof(dp)); dp[1][0][0] = x*t; for(int i = 2;i <= n;i++) { for(int g = 0;g <= i;g++) { int b = 0; for(b = 0;b+g < i;b++) dp[i][g][b] = dp[i-1][g][b]+(g*y+x)*(b*z+t); if(g > 0) dp[i][g][b] = max(dp[i][g][b],dp[i-1][g-1][b]+y*(g-1)*(b*z+t)); if(b > 0) dp[i][g][b] = max(dp[i][g][b],dp[i-1][g][b-1]+g*y*((b-1)*z+t)); } } LL ans = 0; for(int i = 0;i <= n;i++) { for(int j = 0;j+i <= n;j++) ans = max(ans,dp[n][i][j]); } cout << ans << endl; } return 0; }
#include<bits/stdc++.h> using namespace std; long long n,x,y,z,t,dp[105][105]; int main() { ios::sync_with_stdio(0); while(cin >> n) { cin >> x >> y >> z >> t; dp[0][0] = x*t; dp[1][0] = 0; dp[0][1] = 0; for(int i = 2;i <= n;i++) { for(int g = i;g >= 0;g--) { for(int b = i-g;b >= 0;b--) { if(b+g != i) dp[g][b] = dp[g][b]+(g*y+x)*(b*z+t); else dp[g][b] = 0; if(g > 0) dp[g][b] = max(dp[g][b],dp[g-1][b]+y*(g-1)*(b*z+t)); if(b > 0) dp[g][b] = max(dp[g][b],dp[g][b-1]+g*y*((b-1)*z+t)); } } } long long ans = 0; for(int i = 0;i <= n;i++) { for(int j = 0;j+i <= n;j++) ans = max(ans,dp[i][j]); } cout << ans << endl; } return 0; }
#include<bits/stdc++.h> using namespace std; long long n,x,y,z,t,dp[105][105]; int main() { ios::sync_with_stdio(0); while(cin >> n) { cin >> x >> y >> z >> t; memset(dp,0,sizeof(dp)); dp[0][0] = x*t*n; for(int g = 0;g <= n;g++) { for(int b = 0;b+g <= n;b++) { if(g == 0 && b == 0) continue; if(g > 0) dp[g][b] = max(dp[g][b],dp[g-1][b]-x*(b*z+t)+y*(b*z+t)*(n-g-b)); if(b > 0) dp[g][b] = max(dp[g][b],dp[g][b-1]-x*((b-1)*z+t)+(g*y+x)*z*(n-g-b)); } } long long ans = 0; for(int i = 0;i <= n;i++) { for(int j = 0;j+i <= n;j++) ans = max(ans,dp[i][j]); } cout << ans << endl; } return 0; }
1003.高精度模拟。
#include<bits/stdc++.h> using namespace std; int change1(char a) { if(a <= '9') return a-'0'; return a-'A'+10; } char change2(int a) { if(a <= 9) return a+'0'; else return a-10+'A'; } string s1,s2; int n,ans[105]; int main() { ios::sync_with_stdio(0); while(cin >> n) { cin >> s1 >> s2; int p1 = s1.length()-1,p2 = s2.length()-1,cnt = 0,temp = 0; while(p1 >= 0 && p2 >= 0) { int now = change1(s1[p1--])+change1(s2[p2--])+temp; ans[++cnt] = now%n; temp = now/n; } while(p1 >= 0) { int now = change1(s1[p1--])+temp; ans[++cnt] = now%n; temp = now/n; } while(p2 >= 0) { int now = change1(s2[p2--])+temp; ans[++cnt] = now%n; temp = now/n; } if(temp) ans[++cnt] = temp; for(int i = cnt;i > 0;i--) cout << change2(ans[i]); cout << endl; } return 0; }
1004.每次固定一个对应点,旋转5次,暴力比较。
#include<bits/stdc++.h> using namespace std; int a[15],b[15],c[15],d[15]; int point[12][2] = {{1,12},{2,7},{3,8},{4,9},{5,10},{6,11},{7,2},{8,3},{9,4},{10,5},{11,6},{12,1}}; int x[12][10] = {{2,3,4,5,6,10,11,7,8,9},{1,6,9,10,3,5,8,12,11,4},{11,4,1,2,10,7,5,6,9,12},{1,3,11,7,5,2,10,12,8,6}, {1,4,7,8,6,3,11,12,9,2},{1,5,8,9,2,4,7,12,10,3},{4,11,12,8,5,3,10,9,6,1},{12,9,6,5,7,10,2,1,4,11}, {6,8,12,10,2,5,7,11,3,1},{2,9,12,11,3,6,8,7,4,1},{3,10,12,7,4,2,9,8,5,1},{9,8,7,11,10,6,5,4,3,2}}; int ok() { for(int i = 0;i < 10;i++) { if(c[i] != d[i]) return 0; } return 1; } int main() { ios::sync_with_stdio(0); int T; cin >>T; while(T--) { for(int i = 1;i <= 12;i++) cin >> a[i]; for(int i = 1;i <= 12;i++) cin >> b[i]; for(int i = 0;i < 10;i++) c[i] = b[x[0][i]]; int flag = 0; for(int i = 0;i < 12;i++) { if(a[point[i][0]] == b[1] && a[point[i][1]] == b[12]) { for(int j = 0;j < 10;j++) d[j] = a[x[i][j]]; for(int j = 0;j < 5;j++) { if(ok()) flag = 1; int t = d[4]; for(int k = 4;k > 0;k--) d[k] = d[k-1]; d[0] = t; t = d[9]; for(int k = 9;k > 5;k--) d[k] = d[k-1]; d[5] = t; } } } if(flag) cout << "Identical" << endl; else cout << "Different" << endl; } return 0; }
1005.每次除2向上取整,直到最后一根。
#include<bits/stdc++.h> using namespace std; long long n; int main() { while(cin >> n) { int cnt = 0; while(n > 1) { n = n/2+n%2; cnt++; } cout << cnt << endl; } return 0; }
1006.按位运算的dp,a[i],b[i],c[i]分别对应^,|,&,表示从头到i当前位的累和。
#include<bits/stdc++.h> using namespace std; int bin[100005][35],two[35],n; double a[100005],b[100005],c[100005]; int main() { two[0] = 1; for(int i = 1;i <= 30;i++) two[i] = two[i-1]*2; while(cin >> n) { memset(bin,0,sizeof(bin)); int maxcnt = 0; double ans1 = 0,ans2 = 0,ans3 = 0; for(int i = 1,x;i <= n;i++) { cin >> x; ans1 -= x; ans2 -= x; ans3 -= x; int cnt = 0; while(x) { bin[i][++cnt] = x%2; x /= 2; } maxcnt = max(cnt,maxcnt); } for(int j = 1;j <= maxcnt;j++) { int last0 = 0,last1 = 0; for(int i = 1;i <= n;i++) { if(bin[i][j] == 1) { if(last1 > 0) a[i] = a[last1-1]+i-last1; else a[i] = i; b[i] = i-last0; c[i] = i; last1 = i; } else { if(i > 1) a[i] = a[i-1]; else a[i] = 0; b[i] = 0; c[i] = last1; last0 = i; } ans1 += a[i]*two[j]; ans2 += b[i]*two[j]; ans3 += c[i]*two[j]; } } cout << fixed << setprecision(3) << ans1/n/n << " " << fixed << setprecision(3) << ans2/n/n << " " << fixed << setprecision(3) << ans3/n/n << endl; } return 0; }
1007.dp[i][j]表示i个蛋,j层需要的最多次数,另外可以发现k层最多需要logn+1个蛋,复杂度O(n^2*min(logn,k))。
发现对于每一个dp[i][j]的状态,并不需要枚举每一层,因为这是一个先递减,再递增的函数,二分找最低点即可,复杂度O(nlogn*min(logn,k))。
还可以继续优化很多,具体请参考这篇论文https://pan.baidu.com/s/1htXipWsA9mYKaSzhSNYlqw
#include<bits/stdc++.h> using namespace std; int dp[1005][1005]; int main() { int n,k; while(cin >> n >> k) { memset(dp,0x3f,sizeof(dp)); for(int i=0;i<=n;i++) { dp[i][0]=0; dp[i][1]=1; } for(int i=0;i<=k;i++) dp[1][i]=i; for(int j=2;j<=k;j++) { for(int i=2;i<=n;i++) { for(int t=1;t<=j;t++) dp[i][j]=min(dp[i][j],max(dp[i-1][t-1],dp[i][j-t])+1); } } cout << dp[n][k] << endl; } return 0; }
#include<bits/stdc++.h> using namespace std; int n,k,dp[1005][1005]; int main() { ios::sync_with_stdio(0); while(cin >> n >> k) { for(int i = 0;i <= n;i++) { dp[i][0] = 0; dp[i][1] = 1; } n = min(n,int(log(k)/log(2)+1)); for(int i = 0;i <= k;i++) dp[1][i] = i; for(int j = 2;j <= k;j++) { for(int i = 2;i <= n;i++) { int l = 1,r = j; while(l < r) { int mid = (l+r+1)/2; if(dp[i-1][mid-1] <= dp[i][j-mid]) l = mid; else r = mid-1; } dp[i][j] = min(dp[i][j-l],dp[i-1][l])+1; } } cout << dp[n][k] << endl; } return 0; }
1008.约瑟夫环。
#include<bits/stdc++.h> using namespace std; int n,k; int nextt[200005],lastt[200005]; int main() { while(cin >> n >> k) { for(int i = 1;i < n;i++) nextt[i] = i+1; for(int i = 2;i <= n;i++) lastt[i] = i-1; nextt[n] = 1; lastt[1] = n; cout << k;; nextt[lastt[k]] = nextt[k]; lastt[nextt[k]] = lastt[k]; int cnt = n-1,now = nextt[k]; while(cnt) { int left = (k-1)%cnt; while(left--) now = nextt[now]; cout << " " << now; nextt[lastt[now]] = nextt[now]; lastt[nextt[now]] = lastt[now]; now = nextt[now]; cnt--; } cout << endl; } return 0; }
1009.约瑟夫环线段树实现,查找和更新一起做了。
#include<bits/stdc++.h> using namespace std; struct segtree { int left,right,sum; }tree[800005]; void build(int pos,int l,int r) { tree[pos].left = l; tree[pos].right = r; if(l == r) { tree[pos].sum = 1; return; } int mid = (l+r)/2; build(pos*2,l,mid); build(pos*2+1,mid+1,r); tree[pos].sum = tree[pos*2].sum+tree[pos*2+1].sum; } int update(int pos,int num) { tree[pos].sum--; if(tree[pos].left == tree[pos].right) return tree[pos].left; if(num <= tree[pos*2].sum) return update(pos*2,num); else return update(pos*2+1,num-tree[pos*2].sum); } int main() { int n,m; while(cin >> n >> m) { build(1,1,n); cout << m; int now = m; update(1,now); for(int i = 2;i <= n;i++) { now = (now+m-1)%tree[1].sum; if(now == 0) now = tree[1].sum; cout << " " << update(1,now); } cout << endl; } return 0; }
1010.分为两段ab和cd,预处理,枚举中点,求两段的和的最大值。
#include<bits/stdc++.h> using namespace std; int lmax[100005],rmax[100005],a[100005],n; int main() { ios::sync_with_stdio(false); int T; cin >> T; while(T--) { cin >> n; for(int i = 1;i <= n;i++) cin >> a[i]; int minn = a[1]; lmax[1] = -1e9; for(int i = 2;i <= n;i++) { lmax[i] = max(lmax[i-1],a[i]-minn); minn = min(minn,a[i]); } int maxx = a[n]; rmax[n] = -1e9; for(int i = n-1;i >= 1;i--) { rmax[i] = max(rmax[i+1],maxx-a[i]); maxx = max(maxx,a[i]); } int ans = -1e9; for(int i = 2;i < n-2;i++) ans = max(lmax[i]+rmax[i+1],ans); cout << ans << endl; } return 0; }
1011.规律。
#include<bits/stdc++.h> using namespace std; long long n; int main() { ios::sync_with_stdio(false); while(cin >> n) { long long y = sqrt(n); if(y*y <= n) y++; if(y%2) cout << "even" << endl; else cout << "odd" << endl; } return 0; }
1012.KMP的运用,先将串反转。
#include<bits/stdc++.h> using namespace std; int nextt[400005]; string s; void get_next(int len) { int i = 0,j = -1; nextt[0] = -1; while(i < len) { if(j == -1 || s[len-i-1] == s[len-j-1]) nextt[++i] = ++j; else j = nextt[j]; } } int main () { while(cin >> s) { int endd = s.length(); get_next(endd); int maxlen = 0,maxcnt = 0; for(int i = 1;i <= endd;i++) { int len = i-nextt[i]; if(len && i%len == 0) { int cnt = i/len; if(cnt >= maxcnt) { maxcnt = cnt; maxlen = len; } } } if(maxcnt > 1) cout << s.substr(endd-maxlen) << " " << maxcnt << endl; else cout << -1 << endl; } return 0; }
1013.求一个累和。
#include<iostream> #include<cstdio> #include<cstring> using namespace std; int n,m,a[100005],b[100005]; int main() { while(cin >> n) { long long sum = 0; memset(b,0,sizeof(b)); for(int i = 1;i <= n;i++) cin >> a[i]; cin >> m; for(int i = 1,l,r,k;i <= m;i++) { cin >> l >> r >> k; b[l+1] -= k; b[r+1] += k; } for(int i = 1;i <= n;i++) { b[i] += b[i-1]; a[i] += b[i]; sum += a[i]; } int ave = sum/n; for(int i = 1;i <= n;i++) a[i] -= ave; sum = 0; for(int i = 1;i <= n;i++) sum += (long long)a[i]*a[i]; cout << sum << endl; } return 0; }
1014.求最大值期望。
先将l,r和210转化为1-n的数,问题就成了求k次取1-n中的数,求最大值的数学期望。
参考:http://www.zhihu.com/question/30463955?sort=created
#include<bits/stdc++.h> using namespace std; int l,r; double x[305]; int main() { while(cin >> l >> r) { if(l < 210 && r <= 210) { cout << "stupid" << endl; continue; } if(l >= 210) { cout << 1 << endl; continue; } int m = r-l+1,ok = 210-l+1; for(int i = 1;i <= m;i++) x[i] = 1; double now = 300; int ans = 0; while(m - now <= ok-1e-6) { now = 0; for(int i = 1;i <= m-1;i++) { x[i] *= (double)i/m; now += x[i]; } ans++; } cout << ans << endl; } return 0; }
1015.先确定最多的位数,然后从高位开始贪心。
#include<bits/stdc++.h> using namespace std; int n,w[10]; int main() { ios::sync_with_stdio(0); while(~scanf("%d",&n)) { int minn = 1e9; for(int i = 1;i <= 9;i++) { scanf("%d",&w[i]); minn = min(minn,w[i]); } if(n < minn) { printf("-1\n"); continue; } int cnt = n/minn,t = n%minn,now = 9; while(n >= minn) { while(t+minn < w[now]) now--; printf("%d",now); n -= w[now]; t += minn-w[now]; } printf("\n"); } return 0; }
1016.a+b。
#include<bits/stdc++.h> using namespace std; int main() { ios::sync_with_stdio(false); long long a,b; while(cin >> a >> b) cout << a+b << endl; return 0; }
1017.排序。
#include<bits/stdc++.h> using namespace std; int n; struct aa { string name; int rating; friend bool operator <(aa x,aa y) { if(x.rating != y.rating) return x.rating > y.rating; return x.name < y.name; } }a[10005]; int main() { ios::sync_with_stdio(false); while(cin >> n && n) { for(int i = 0;i < n;i++) cin >> a[i].name >> a[i].rating; sort(a,a+n); for(int i = 0;i < n;i++) cout << a[i].name << " " << a[i].rating << endl; } return 0; }
1018.约瑟夫环数学结论。
#include<bits/stdc++.h> using namespace std; int n,k,t; int fun(int x) { int a = (n-x+k)%(n-x+1); for(int i = 2;i <= x;) { int temp = min(x+1-i,(n-x+i-a-1)/k+1); a = (a+k*temp)%(n-x+i+temp-1); i += temp; } return a; } int main() { while(cin >> n >> k >> t) { int x; cin >> x; cout << fun(x)+1; while(--t) { cin >> x; cout << " " << fun(x)+1; } cout << endl; } return 0; }
1019.末尾0由2*5构成,2足够多,看5的数量就可以了。注意25是2个5,125是3个5...先用等比公式推出趋于极限时,n = m*4,但实际可能比这个数大一点,再向上找。
或者直接二分找5的个数大于等于n的最小值,再判断。
#include<bits/stdc++.h> using namespace std; int n; int f(int x) { int now = 5,ans = 0; while(now <= x) { ans += x/now; now *= 5; } return ans; } int main() { ios::sync_with_stdio(false); int T; cin >> T; while(T--) { cin >> n; int ans = n*4; while(f(ans) < n) ans++; if(f(ans) == n) cout << ans << endl; else cout << "No solution" << endl; } return 0; }
1020.概率dp,dp[i][j]表示前i题对j题的概率。
#include<bits/stdc++.h> using namespace std; int n,k; double a[1005],dp[1005][1005]; int main() { ios::sync_with_stdio(false); int T; cin >> T; while(T--) { cin >> n >> k; for(int i = 1;i <= n;i++) cin >> a[i]; dp[1][0] = 1-a[1]; dp[1][1] = a[1]; for(int i = 2;i <= n;i++) { dp[i][0] = dp[i-1][0]*(1-a[i]); for(int k = 1;k <= n;k++) dp[i][k] = dp[i-1][k]*(1-a[i])+dp[i-1][k-1]*a[i]; } double ans = 0; for(int i = k;i <= n;i++) ans += dp[n][i]; cout << fixed << setprecision(4) << ans << endl; } return 0; }
1021.分割成三角形,求面积和。
#include<bits/stdc++.h> #define PI atan(1)*4 using namespace std; int main() { int T; cin >> T; while(T--) { int n; double x; cin >> n >> x; cout << fixed << setprecision(4) << 0.25*n*x*x/tan(PI/n) <<endl; } return 0; }
1022.统计每个数被加了多少次,两次前缀和。
#include<bits/stdc++.h> using namespace std; int sum[1000005]; int main() { ios::sync_with_stdio(false); for(int i = 1;i <= 1000000;i++) { for(int j = i;j <= 1000000;j += i) sum[j]++; } for(int i = 2;i <= 1000000;i++) sum[i] = (sum[i]+sum[i-1])%1007; for(int i = 2;i <= 1000000;i++) sum[i] = (sum[i]+sum[i-1])%1007; int a,b; while(cin >> a >> b) cout << (sum[b]-sum[a-1]+1007)%1007 << endl; return 0; }
1023.区间不交叉,直接排序,二分按r中找r满足最左段,判断是否在该段中。
#include<bits/stdc++.h> using namespace std; int n,m; struct city { int l,r,id; city(){}; city(int ll,int rr,int idd):l(ll),r(rr),id(idd){}; friend bool operator <(city x,city y) { return x.r < y.r; } }a[100005]; int main() { ios::sync_with_stdio(false); int T; scanf("%d",&T); while(T--) { scanf("%d",&n); for(int i = 1;i <= n;i++) scanf("%d%d%d",&a[i].l,&a[i].r,&a[i].id); sort(a+1,a+n+1); scanf("%d",&m); while(m--) { int ip; scanf("%d",&ip); int ans = lower_bound(a+1,a+1+n,city(0,ip,0))-a; if(ans == n+1 || ip < a[ans].l) printf("-1\n"); else printf("%d\n",a[ans].id); } } return 0; }
1024.树状数组维护一下前缀和。
#include<bits/stdc++.h> #define MOD 1000000007 using namespace std; int n,tree[15]; inline int lowbit(int x) { return x&-x; } void add(int pos,int x) { while(pos <= 10) { tree[pos] += x; pos += lowbit(pos); } } int getsum(int pos) { int sum = 0; while(pos > 0) { sum += tree[pos]; pos -= lowbit(pos); } return sum; } int main() { ios::sync_with_stdio(false); int T; scanf("%d",&T); while(T--) { memset(tree,0,sizeof(tree)); scanf("%d",&n); long long ans = 0; for(int i = 1;i <= n;i++) { int x; scanf("%d",&x); add(x+1,1); ans = (ans+i-getsum(x+1))%MOD; } printf("%lld\n",ans); } return 0; }
1025.记忆化dp。
#include<bits/stdc++.h> using namespace std; vector<int> make[10005]; int v[10005],dp[10005],n,m,w; int dfs(int x) { if(dp[x] != -1) return dp[x]; dp[x] = v[x]; if(!make[x].empty()) { int sum = w; for(int i = 0;i < make[x].size();i++) sum += dfs(make[x][i]); dp[x] = min(dp[x],sum); } return dp[x]; } int main() { int T; scanf("%d",&T); while(T--) { memset(dp,-1,sizeof(dp)); scanf("%d%d%d",&n,&m,&w); for(int i = 0;i < n;i++) make[i].clear(); for(int i = 0,cnt;i < n;i++) { scanf("%d%d",&v[i],&cnt); for(int j = 1;j <= cnt;j++) { int x; scanf("%d",&x); make[i].push_back(x); } } int ans = 0; for(int i = 1;i <= m;i++) { int x; scanf("%d",&x); ans += dfs(x); } printf("%d\n",ans); } return 0; }
1026.快速幂模版。
#include<bits/stdc++.h> using namespace std; long long a,b,c; long long qpower(long long a, long long b, long long c) { long long ans = 1; a = a%c; while(b) { if(b%2) ans = ans*a%c; a = a*a%c; b /= 2; } return ans; } int main() { ios::sync_with_stdio(0); while(cin >> a >> b >> c) cout << qpower(a,b,c) << endl; return 0; }
1027.矩阵快速幂模版。
#include<bits/stdc++.h> #define MOD 1000000007 using namespace std; int n; struct matrix { long long m[2][2]; }; matrix one = { 1,0, 0,1 }; matrix base = { 2,1, 1,0 }; matrix mul(matrix a, matrix b) { matrix tmp; for(int i = 0; i < 2;i++) { for(int j = 0; j < 2;j++) { tmp.m[i][j] = 0; for(int k = 0; k < 2;k++) tmp.m[i][j] = (tmp.m[i][j]+a.m[i][k]*b.m[k][j])%MOD; } } return tmp; } long long fast_mod(int n) { matrix ans = one,y = base; while(n) { if(n&1) ans = mul(ans,y); y = mul(y,y); n /= 2; } return ans.m[0][0]; } int main() { while(cin >> n) cout << fast_mod(n-1) << endl; return 0; }
1028.素数筛,dp求最小花费。
#include<bits/stdc++.h> using namespace std; int n,cnt = 0,vis[1000005] = {0},prime[100000],dp[1000005]; void getprime(int MAXN) { for(int i = 2;i <= MAXN;i++) { if(!vis[i]) prime[++cnt] = i; for(int j = 1;j <= cnt && (long long)i*prime[j] <= MAXN;j++) { vis[prime[j]*i] = 1; if(!(i%prime[j])) break; } } } int main() { getprime(1000000); memset(dp,0x3f,sizeof(dp)); dp[1] = 0; for(int i = 1;i <= 1000000;i++) { dp[i+1] = min(dp[i]+1,dp[i+1]); for(int j = 1;j <= cnt && i*prime[j] <= 1000000;j++) { int t = i*prime[j]; dp[t] = min(dp[i]+1,dp[t]); } } while(~scanf("%d",&n)) printf("%d\n",dp[n]); return 0; }
1029.首位化log再化回来,末尾快速幂模10。
#include<bits/stdc++.h> using namespace std; int n; long long PowerMod(int a, int b, int c) { long long ans = 1; a = a%c; while(b > 0) { if(b % 2 == 1) ans = (ans*a)%c; b = b/2; a = (a*a)%c; } return ans; } int main() { int T; cin >> T; while(T--) { cin >> n; double x = log10(2)*n; int ans = pow(10,x-(int)x)+1e-6; cout << ans << " " << PowerMod(2,n,10) << endl; } return 0; }
1030.排序后枚举前两个,二分第三个。
#include<bits/stdc++.h> using namespace std; int a[1005],n; int main() { ios::sync_with_stdio(false); while(cin >> n) { int flag = 1; for(int i = 1;i <= n;i++) cin >> a[i]; sort(a+1,a+1+n); for(int i = 1;i <= n-2;i++) { for(int j = i+1;j <= n-1;j++) { int sum = -a[i]-a[j]; int pos = lower_bound(a+j+1,a+n+1,sum)-a; if(pos != n+1 && a[pos] == sum) { flag = 0; cout << a[i] << " " << a[j] << " " << a[pos] << endl; } } } if(flag) cout << "Ren Chou Jiu Gai Duo Du Shu!" << endl; } return 0; }
1031.规律,a[i][j] = (i+j)/gcd(i,j)。
#include<bits/stdc++.h> using namespace std; int n,m; int main() { ios::sync_with_stdio(false); while(cin >> n >> m) { int ans = 0; for(int i = 1;i <= n;i++) { for(int j = 1;j <= m;j++) { ans += (i+j)/__gcd(i,j); } } cout << ans << endl; } return 0; }
1032.规律,组合数,lacus模版。
#include<bits/stdc++.h> #define LL long long using namespace std; LL n,m; LL PowerMod(LL a, LL b, LL c) { LL ans = 1; a = a % c; while(b) { if(b&1) ans = (ans*a)%c; b = b>>1; a = (a*a)%c; } return ans; } LL c(LL m,LL n) { if(m < n) return 0; if(m == n) return 1; if(n > m-n) n = m-n; LL mm = 1,nn = 1; for(LL i = 0;i < n;i++) { mm = mm*(m-i)%10007; nn = nn*(n-i)%10007; } return mm*PowerMod(nn,10005,10007)%10007; } LL lucas(LL m,LL n) { LL ans = 1; while(m && n && ans) { ans = ans%10007*c(m%10007,n%10007)%10007; n /= 10007; m /= 10007; } return ans; } int main() { ios::sync_with_stdio(false); while(cin >> n >> m) cout << lucas(m,n) << endl; return 0; }
1033.直接比较。
#include<bits/stdc++.h> using namespace std; int main() { ios::sync_with_stdio(false); int T; cin >> T; while(T--) { int a; cin >> a; if(a <= 540) cout << "YES" << endl; else cout << "NO" << endl; } return 0; }
1034.直接模拟。
#include<bits/stdc++.h> using namespace std; int n; int main() { int n,T; cin >> T; while(T--) { cin >> n; int sub = 1,ans = 1; while(n > sub) { n -= sub; ans++; sub *= 2; } if(n <= sub/2) cout << ans-1 << " " << sub/2 << endl; else cout << ans << " " << n << endl; } return 0; }
1035.set去重判断。
#include<bits/stdc++.h> using namespace std; int a[10][10]; int x[9] = {1,1,1,4,4,4,7,7,7},y[9] = {1,4,7,1,4,7,1,4,7}; set<int> s; int main() { ios::sync_with_stdio(false); int T; cin >> T; while(T--) { int flag = 1; for(int i = 1;i <= 9;i++) { s.clear(); for(int j = 1;j <= 9;j++) { cin >> a[i][j]; if(a[i][j] == 0 || a[i][j] > 9) flag = 0; s.insert(a[i][j]); } if(s.size() != 9) flag = 0; } for(int j = 1;j <= 9;j++) { s.clear(); for(int i = 1;i <= 9;i++) s.insert(a[i][j]); if(s.size() != 9) flag = 0; } for(int k = 0;k < 9;k++) { s.clear(); for(int i = x[k],cnt1 = 0;cnt1 < 3;i++,cnt1++) { for(int j = y[k],cnt2 = 0;cnt2 < 3;j++,cnt2++) s.insert(a[i][j]); } if(s.size() != 9) flag = 0; } there: if(flag) cout << "yes" << endl; else cout << "no" << endl; } return 0; }
1036.容量为sum/2的01背包。
#include<bits/stdc++.h> using namespace std; int n,w[205],dp[200005]; int main() { int T; cin >> T; while(T--) { memset(dp,0,sizeof(dp)); int sum = 0; cin >> n; for(int i = 1;i <= n;i++) { cin >> w[i]; sum += w[i]; } int endd = sum/2; for(int i = 1;i <= n;i++) { for(int j = endd;j >= w[i];j--) { dp[j] = max(dp[j],dp[j-w[i]]+w[i]); } } cout << sum-dp[endd]*2 << endl; } return 0; }
1037.构造逆向逆数b,然后找a的后缀和b的前缀相同的部分。
#include<bits/stdc++.h> using namespace std; int a[55],b[55]; string s; int main() { int T; cin >> T; while(T--) { cin >> s; int n = s.length(); for(int i = 1;i <= n;i++) { a[i] = s[i-1]-'0'; b[n-i+1] = a[i]^1; } int pos; for(pos = 1;pos <= n;pos++) { int flag = 1; for(int i = pos,j = 1;i <= n;i++,j++) { if(a[i] != b[j]) { flag = 0; break; } } if(flag) break; } for(int i = 1;i < pos;i++) cout << a[i]; for(int i = 1;i <= n;i++) cout << b[i]; cout << endl; } return 0; }
1038.状压dp。
#include<bits/stdc++.h> using namespace std; int a[15][15],sta[100],dp[15][100],sum[15][100],n,m; int main() { ios::sync_with_stdio(false); int T; cin >> T; while(T--) { memset(dp,0,sizeof(dp)); memset(sum,0,sizeof(sum)); cin >> n >> m; for(int i = 1;i <= n;i++) { for(int j = 1;j <= m;j++) cin >> a[i][j]; } int cnt = 0,endd = 1<<(m-1); for(int i = 0;i < endd;i++) { if(i & (i<<1)) continue; sta[++cnt] = i; } for(int i = 1;i < n;i++) { for(int j = 1;j <= cnt;j++) { for(int k = 1;k <= m-1;k++) { if(1<<(k-1) & sta[j]) { if(a[i][k] && a[i][k+1] && a[i+1][k] && a[i+1][k+1]) sum[i][j]++; } } } } for(int i = 1;i <= cnt;i++) dp[1][i] = sum[1][i]; for(int i = 1;i < n;i++) { for(int j = 1;j <= cnt;j++) { for(int k = 1;k <= cnt;k++) { dp[i+2][k] = max(dp[i+2][k],dp[i][j]+sum[i+2][k]); if(sta[j] & sta[k]) continue; if(sta[j] & (sta[k]<<1)) continue; if(sta[j] & (sta[k]>>1)) continue; dp[i+1][k] = max(dp[i+1][k],dp[i][j]+sum[i+1][k]); } } } int ans = 0; for(int i = 1;i <= cnt;i++) ans = max(ans,dp[n-1][i]); cout << ans << endl; } return 0; }
1039.大模拟。
#include<bits/stdc++.h> using namespace std; struct yy { int num,y; friend bool operator<(yy A,yy B) { return A.y > B.y; } }y; struct zz { int num,z; friend bool operator<(zz A,zz B) { return A.z > B.z; } }z; struct xx { int x,last,next; }a[1005]; int eat[1005],die[1005],n,m,live,turn; priority_queue<yy> qy; priority_queue<zz> qz; void fun(int i) { a[i].x--; if(a[i].x == 0) { die[i] = 1; eat[i] = 0; live--; a[a[i].last].next = a[i].next; a[a[i].next].last = a[i].last; } } void eatt(int num) { if(!eat[num]) fun(num); for(int i = 1;i <= n;i++) { if(eat[i]) fun(i); } } int main() { int T; cin >> T; while(T--) { while(!qy.empty()) qy.pop(); while(!qz.empty()) qz.pop(); memset(die,0,sizeof(die)); memset(eat,0,sizeof(eat)); cin >> n >> m; for(int i = 1;i <= n;i++) { a[i].last = i-1; a[i].next = i+1; cin >> a[i].x; } a[1].last = n; a[n].next = 1; for(int i = 1;i <= n;i++) { y.num = i; cin >> y.y; qy.push(y); } for(int i = 1;i <= n;i++) { z.num = i; cin >> z.z; qz.push(z); } turn = 1,live = n; while(m--) { int card,now; cin >> card; if(n == 1) break; switch(card) { case 1: now = qy.top().num; while(die[now]) { qy.pop(); now = qy.top().num; } eatt(now); break; case 2: now = qz.top().num; while(die[now]) { qz.pop(); now = qz.top().num; } eatt(now); break; case 3: eat[turn] = 1; break; case 4: eatt(a[turn].last); break; case 5: eatt(a[turn].next); break; case 6: eatt(turn); break; } if(live == 0) break; turn = a[turn].next; while(die[turn]) turn = a[turn].next; if(live == 1) break; } for(int i = 1;i <= m;i++) { int card; cin >> card; } switch(live) { case 0: cout << 0 << endl; break; case 1: cout << turn << endl; break; default: cout << -1 << endl; break; } } return 0; }
1040.解方程组判断。
#include<bits/stdc++.h> using namespace std; int a,b,c; int main() { int T; cin >> T; while(T--) { cin >> a >> b >> c; int x = (a+b-c)/2,y = (a+c-b)/2,z = (b+c-a)/2; if((x+y+z)*2==(a+b+c)&&1<=x&&x<=100000&&1<=y&&y<=100000&&1<=z&&z<=100000) cout << x << " " << y << " " << z << endl; else cout << "Impossible" << endl; } return 0; }
1041.奇偶性规律。
#include<bits/stdc++.h> using namespace std; int n,m; int main() { int T; cin >> T; while(T--) { cin >> n >> m; if(n%2 || m%2) cout << 1 << endl; else cout << 2 << endl; } return 0; }
1042.每次操作最小的两个数。
#include<bits/stdc++.h> using namespace std; priority_queue<double,vector<double>,greater<double> > q; int n; int main() { int T; cin >> T; while(T--) { cin >> n; for(int i = 1;i <= n;i++) { double temp; cin >> temp; q.push(temp); } for(int i = 1;i < n;i++) { double a = q.top(); q.pop(); double b = q.top(); q.pop(); q.push((a+b)/2); } cout << fixed << setprecision(2) << q.top()+0.00001 << endl; q.pop(); } return 0; }
1043.概率dp,dp[i][j]表示前i天上j节课的概率,等比求和求期望。
#include<bits/stdc++.h> using namespace std; double p[25],dp[25][25]; int n,k; int main() { int T; cin >> T; while(T--) { cin >> n >> k; for(int i = 1;i <= n;i++) cin >> p[i]; dp[0][0] = 1; for(int i = 1;i <= n;i++) { dp[i][0] = dp[i-1][0]*(1-p[i]); for(int j = 1;j <= n;j++) dp[i][j] = dp[i-1][j-1]*p[i]+dp[i-1][j]*(1-p[i]); } double x = 0; for(int i = k;i <= n;i++) x += dp[n][i]; cout << x/(1-x) << endl; } return 0; }
1044.枚举所有情况就可以了,注意每种牌最多只有4张。
#include<bits/stdc++.h> using namespace std; int dp[15][15][15] = {0},a[3]; void init() { for(int i = 9;i >= 1;i--) dp[i][i][i] = dp[i+1][i+1][i+1]+1; dp[7][8][9] = 9; for(int i = 6;i >= 1;i--) dp[i][i+1][i+2] = dp[i+1][i+2][i+3]+1; int x = 1,y = 2,z = 3; dp[1][2][3] -= 1; for(int i = 9;i >= 1;i--) { int j; for(j = 9;j > i;j--) { dp[i][i][j] = dp[x][y][z]+1; x = i; y = i; z = j; } for(j--;j >= 1;j--) { dp[j][i][i] = dp[x][y][z]+1; x = j; y = i; z = i; } } dp[1][2][3] += 1; dp[1][1][2] += 1; for(int k = 9;k >= 1;k--) { for(int j = k-1;j >= 1;j--) { for(int i = j-1;i >= 1;i--) { if(dp[i][j][k]) continue; dp[i][j][k] = dp[x][y][z]+1; x = i; y = j; z = k; } } } dp[1][1][2] -= 1; dp[2][3][5] += 9; } int main() { ios::sync_with_stdio(false); init(); int T; cin >> T; while(T--) { cin >> a[0] >> a[1] >> a[2]; sort(a,a+3); cout << dp[a[0]][a[1]][a[2]] << endl; } return 0; }
1045.博弈dfs,注意dfs过程中还原原图。
#include<bits/stdc++.h> using namespace std; string a[10]; int dir[4][2] = {-1,0,0,-1,1,0,0,1}; bool dfs(int x,int y) { a[x][y] = '1'; for(int i = 0;i < 4;i++) { int xx = x+dir[i][0],yy = y+dir[i][1]; if(xx > 5 || xx < 1 || yy > 5 || yy < 1 || a[xx][yy] == '1') continue; if(dfs(xx,yy)) { a[x][y] = '0'; return 0; } } a[x][y] = '0'; return 1; } int main() { int T; cin >> T; while(T--) { for(int i = 1;i <= 5;i++) { cin >> a[i]; a[i] = " "+a[i]; } int flag = 0; for(int i = 1;i <= 5;i++) { for(int j = 1;j <= 5;j++) { if(a[i][j] == '0' && dfs(i,j)) { flag = 1; break; } } if(flag) break; } if(flag) cout << "win" << endl; else cout << "lose" << endl; } return 0; }
1046.string类型的高精度。
#include<bits/stdc++.h> using namespace std; int compare(string str1,string str2) { if(str1.length() > str2.length()) return 1; else if(str1.length() < str2.length()) return -1; else return str1.compare(str2); } string add(string str1,string str2) { string str; int len1 = str1.length(),len2 = str2.length(); if(len1 < len2) { for(int i = 1;i <= len2-len1;i++) str1 = "0"+str1; } else { for(int i = 1;i <= len1-len2;i++) str2 = "0"+str2; } int cf = 0,temp; for(int i = str1.length()-1;i >= 0;i--) { temp = str1[i]-'0'+str2[i]-'0'+cf; cf = temp/10; temp %= 10; str = char(temp+'0')+str; } if(cf != 0) str = char(cf+'0')+str; return str; } string sub(string str1,string str2) { string str; int flag = 0; if(compare(str1,str2) < 0) { flag = 1; swap(str1,str2); } int tmp = str1.length()-str2.length(),cf = 0; for(int i = str2.length()-1;i >= 0;i--) { if(str1[tmp+i] < str2[i]+cf) { str = char(str1[tmp+i]-str2[i]-cf+'0'+10)+str; cf = 1; } else { str = char(str1[tmp+i]-str2[i]-cf+'0')+str; cf = 0; } } for(int i = tmp-1;i >= 0;i--) { if(str1[i]-cf >= '0') { str = char(str1[i]-cf)+str; cf = 0; } else { str = char(str1[i]-cf+10)+str; cf = 1; } } str.erase(0,str.find_first_not_of('0')); if(str.empty()) str = "0"; if(flag) str = "-"+str; return str; } string mul(string str1,string str2) { string str; int len1 = str1.length(); int len2 = str2.length(); string tempstr; for(int i = len2-1;i >= 0;i--) { tempstr = ""; int temp = str2[i]-'0',t = 0,cf = 0; if(temp != 0) { for(int j = 1;j <= len2-1-i;j++) tempstr += "0"; for(int j = len1-1;j >= 0;j--) { cf = (temp*(str1[j]-'0')+cf); t = cf%10; cf /= 10; tempstr = char(t+'0')+tempstr; } if(cf != 0) tempstr = char(cf+'0')+tempstr; str=add(str,tempstr); } } str.erase(0,str.find_first_not_of('0')); if(str.empty()) str = "0"; return str; } void div(string str1,string str2,string "ient,string &residue) { quotient = ""; residue = ""; if(str2 == "0") { quotient = "ERROR"; residue = "ERROR"; return; } if(str1 == "0") { quotient = "0"; residue = "0"; return; } int res = compare(str1,str2); if(res < 0) { quotient = "0"; residue = str1; return; } else { int len1 = str1.length(); int len2 = str2.length(); string tempstr; tempstr.append(str1,0,len2-1); for(int i = len2-1;i < len1;i++) { tempstr = tempstr+str1[i]; tempstr.erase(0,tempstr.find_first_not_of('0')); if(tempstr.empty()) tempstr = "0"; for(char ch = '9';ch >= '0';ch--) { string str,tmp; str = str+ch; tmp = mul(str2,str); if(compare(tmp,tempstr) <= 0) { quotient = quotient+ch; tempstr = sub(tempstr,tmp); break; } } } residue = tempstr; } quotient.erase(0,quotient.find_first_not_of('0')); if(quotient.empty()) quotient = "0"; } int main() { string str1,str2; string str3,str4; while(cin >> str1 >> str2) { div(str1,str2,str3,str4); cout << add(str1,str2) << ' ' << sub(str1,str2) << ' ' << mul(str1,str2) << ' ' << str3 << ' ' << str4 << endl; } return 0; }
1048.二分匹配模版。
#include<bits/stdc++.h> using namespace std; int n,m,l; int linker[505]; bool used[505]; vector<int> v[505]; bool dfs(int u) { for(int i = 0;i < v[u].size();i++) { int t = v[u][i]; if(used[t]) continue; used[t] = 1; if(linker[t] == -1 || dfs(linker[t])) { linker[t] = u; return 1; } } return 0; } int MaxMatch() { int ans = 0; memset(linker,-1,sizeof(linker)); for(int i = 0;i < n;i++) { memset(used,0,sizeof(used)); if(dfs(i)) ans++; } return ans; } int main() { ios::sync_with_stdio(false); while(cin >> n >> m) { for(int i = 0;i < n;i++) v[i].clear(); cin >> l; for(int i = 0,a,b;i < l;i++) { cin >> a >> b; v[a].push_back(b); } cout << MaxMatch() << endl; } return 0; }
1053.直接判断正负。
#include<bits/stdc++.h> using namespace std; int n; int main() { while(cin >> n) { if(n > 0) cout << "yes" << endl; else if(n < 0) cout << "no" << endl; else cout << "light" << endl; } return 0; }
1054.权值累加。
#include<bits/stdc++.h> using namespace std; int n,a[10] = {1,0,0,0,0,0,1,0,2,1}; int main() { ios::sync_with_stdio(false); while(cin >> n) { int ans = 0; while(n) { ans += a[n%10]; n /= 10; } cout << ans << endl; } return 0; }
1055.模拟遍历。
include<bits/stdc++.h> using namespace std; int a[55][55],ans[2505],n,m; int main() { ios::sync_with_stdio(false); while(cin >> n >> m) { int total = n*m; for(int i = 1;i <= n;i++) { for(int j = 1;j <= m;j++) cin >> a[i][j]; } int now = 1,x = 1,y = 1; ans[1] = a[1][1]; while(now < total) { if(x < n) ans[++now] = a[++x][y]; else ans[++now] = a[x][++y]; while(x > 1 && y < m) ans[++now] = a[--x][++y]; if(y < m) ans[++now] = a[x][++y]; else ans[++now] = a[++x][y]; while(x < n && y > 1) ans[++now] = a[++x][--y]; } cout << ans[1]; for(int i = 2;i <= total;i++) cout << " " << ans[i]; cout << endl; } return 0; }
1056.dp。
#include<bits/stdc++.h> using namespace std; int dp[1005][1005] = {0},n; int main() { ios::sync_with_stdio(false); dp[0][0] = 1; for(int i = 1;i <= 1000;i++) { dp[i][0] = 1; for(int j = 1;j < i;j++) dp[i][j] = (dp[i-1][j]+dp[i][j-1])%10007; dp[i][i] = dp[i][i-1]; } while(cin >> n) cout << dp[n][n] << endl; return 0; }
1057.可重复组合,lucas模版。
#include<bits/stdc++.h> #define LL long long using namespace std; LL n,m; LL PowerMod(LL a, LL b, LL c) { LL ans = 1; a = a % c; while(b) { if(b&1) ans = (ans*a)%c; b = b>>1; a = (a*a)%c; } return ans; } LL c(LL m,LL n) { if(m < n) return 0; if(m == n) return 1; if(n > m-n) n = m-n; LL mm = 1,nn = 1; for(LL i = 0;i < n;i++) { mm = mm*(m-i)%10007; nn = nn*(n-i)%10007; } return mm*PowerMod(nn,10005,10007)%10007; } LL lucas(LL m,LL n) { LL ans = 1; while(m && n && ans) { ans = ans%10007*c(m%10007,n%10007)%10007; n /= 10007; m /= 10007; } return ans; } int main() { ios::sync_with_stdio(false); while(cin >> n >> m) cout << lucas(m+n-1,m) << endl; return 0; }
1058.把边的贡献算到点上,贡献大于0的点在子图内,小于0的点在子图外。
#include<bits/stdc++.h> #define LL long long using namespace std; LL a[100005]; int n,m,u,v,w; int main() { ios::sync_with_stdio(false); while(cin >> n >> m) { memset(a,0,sizeof(a)); for(int i = 1;i <= m;i++) { cin >> u >> v >> w; a[u] += w; a[v] += w; } LL ans = 0; for(int i = 1;i <= n;i++) ans += a[i] > 0?a[i]:-a[i]; cout << ans/2 << endl; } return 0; }
1059.按时间以ms为单位模拟,可以用优先队列优化,好像还可以用数学的方法快速算。
#include<bits/stdc++.h> using namespace std; double ha,hb,maxha,maxhb,aa,ab,adda,addb,sub2a,sub2b,sub1a,sub1b,ara,arb; int ta,tb,cool1a,cool1b,cool2a,cool2b; bool cmp(double x,double y) { return x-y > 1e-8; } int main() { ios::sync_with_stdio(0); int T; cin >> T; while(T--) { cin >> ha >> maxha >> aa >> adda >> sub2a >> sub1a >> ara >> ta >> cool1a >> cool2a; cin >> hb >> maxhb >> ab >> addb >> sub2b >> sub1b >> arb >> tb >> cool1b >> cool2b; cool2a *= 1000; cool2b *= 1000; int stopa = 2000/100*(100-ta),stopb = 2000/100*(100-tb); double hita = aa*100/(100+arb*(100-sub1a)/100-sub2a),hitb = ab*100/(100+ara*(100-sub1b)/100-sub2b); int ta_att = 0,tb_att = 0,ta_mag = 0,tb_mag = 0,buffa = 0,buffb = 0,ta_buff = 0,tb_buff = 0,ta_stop = -1,tb_stop = -1; int t = 0; while(1) { if(ta_stop == t) { ta_att = max(ta_att,t+stopa); ta_mag = max(ta_mag,t+stopa); } if(tb_stop == t) { tb_att = max(tb_att,t+stopb); tb_mag = max(tb_mag,t+stopb); } if(--ta_buff <= 0) buffa = 0; if(--tb_buff <= 0) buffb = 0; if(ta_att == t && tb_att == t) { double hitatob = min(hita*(1+0.125*buffa),hb); double hitbtoa = min(hitb*(1+0.125*buffb),ha); hb -= hitatob; ha -= hitbtoa; if(!cmp(ha,0) && !cmp(hb,0)) break; if(!cmp(ha,0)) { hb = min(maxhb,hb+hitbtoa*addb/100); break; } if(!cmp(hb,0)) { ha = min(maxha,ha+hitatob*adda/100); break; } hb = min(maxhb,hb+hitbtoa*addb/100); ha = min(maxha,ha+hitatob*adda/100); buffa = min(buffa+1,4); buffb = min(buffb+1,4); ta_buff = 2000; tb_buff = 2000; ta_att += cool1a; tb_att += cool1b; } else if(ta_att == t) { double hit = min(hita*(1+0.125*buffa),hb); ha = min(maxha,ha+hit*adda/100); hb -= hit; if(!cmp(hb,0)) break; buffa = min(buffa+1,4); ta_buff = 2000; ta_att += cool1a; } else if(tb_att == t) { double hit = min(hitb*(1+0.125*buffb),ha); hb = min(maxhb,hb+hit*addb/100); ha -= hit; if(!cmp(ha,0)) break; buffb = min(buffb+1,4); tb_buff = 2000; tb_att += cool1b; } if(ta_mag == t) { ta_mag = t+cool2a; tb_stop = t+1000; } if(tb_mag == t) { tb_mag = t+cool2b; ta_stop = t+1000; } t++; } if(t%10 >= 5) t = t/10+1; else t = t/10; int t1 = t/100,t2 = t%100; cout << t1 << "." << setw(2) << setfill('0') << t2 << " "; cout << fixed << setprecision(2) << ha+1e-8 << " " << hb+1e-8 << endl; } return 0; }
1060.不知道如何直接输出,手动处理整数。
#include<bits/stdc++.h> using namespace std; int a[25]; long long x; int main() { while(cin >> x) { int cnt = 0; if(x%10 >= 5) x = x/10+1; else x = x/10; if(x == 0) { cout << "0.00" << endl; continue; } while(x) { a[++cnt] = x%10; x /= 10; } if(cnt > 2) { for(;cnt > 2;cnt--) cout << a[cnt]; } else { cout << "0"; } cout << "."; if(cnt == 1) cout << "0"; for(;cnt > 0;cnt--) cout << a[cnt]; cout << endl; } return 0; }
1061.通分后计算,再约分。
#include<bits/stdc++.h> using namespace std; int a1,a2,b1,b2; char c; int main() { while(cin >> a1 >> c >> a2 >> b1 >> c >> b2) { int x = a1*b2+a2*b1,y = a2*b2,g = __gcd(x,y);; cout << x/g << "/" << y/g << endl; } return 0; }
1062.最大连续k段和,注意k小于n的情况。
#include<bits/stdc++.h> using namespace std; int n,t,a[100005]; int main() { while(cin >> n >> t) { for(int i = 1;i <= n;i++) cin >> a[i]; int sum = 0; if(n <= t) { for(int i = 1;i <= n;i++) sum += a[i]; cout << sum << endl; continue; } for(int i = 1;i <= t;i++) sum += a[i]; int ans = sum; for(int l = 1,r = t+1;r <= n;l++,r++) { sum += a[r]; sum -= a[l]; ans = max(ans,sum); } cout << ans << endl; } return 0; }
1063.数学推导,参考https://pan.baidu.com/s/1i3jljoBZWL74nf6_3aVz-A
#include<bits/stdc++.h> #define LL long long #define MOD 1000000007 using namespace std; LL PowerMod(LL a, LL b, LL c) { LL ans = 1; a = a % c; while(b) { if(b&1) ans = (ans*a)%c; b = b>>1; a = (a*a)%c; } return ans; } int main() { int n; while(cin >> n) { if(n == 1) cout << 1 << endl; else if(n%2) cout << PowerMod(2,n-1,MOD) << endl; else cout << (PowerMod(2,n-1,MOD)+PowerMod(2,n/2-1,MOD))%MOD << endl; } return 0; }
1064.将坐标旋转45度,注意长度的变化,然后处理一下重叠面积和方格数量的转化。
#include<bits/stdc++.h> #define LL long long using namespace std; int main() { LL x1,y1,x2,y2,r,X1,Y1,X2,Y2; while(cin >> x1 >> y1 >> x2 >> y2 >> r) { X1 = y1+x1; Y1 = y1-x1; X2 = y2+x2; Y2 = y2-x2; LL a = max(0LL,2*r+2-abs(X1-X2)),b = max(0LL,2*r+2-abs(Y1-Y2)); LL sub = a*b?(a*b-a-b+2)/2:0; cout << 2*(2*r*r+2*r+1)-sub << endl; } return 0; }
1065.动态开点线段树,维护连续最长段。
#include<bits/stdc++.h> using namespace std; int n,q,cnt = 0,a[100005]; struct segtree { int l,r,lazy,len,x,lx,rx; segtree *lson,*rson; }*root,tree[3000005]; segtree *newnode(int l,int r) { segtree *t = &tree[++cnt]; t->l = l; t->r = r; t->lson = NULL; t->rson = NULL; t->lazy = -1; t->len = r-l+1; t->x = t->len; t->lx = t->len; t->rx = t->len; return t; } segtree *newlson(segtree *pos) { int mid = (pos->l+pos->r)/2; return newnode(pos->l,mid); } segtree *newrson(segtree *pos) { int mid = (pos->l+pos->r)/2; return newnode(mid+1,pos->r); } void pushup(segtree *pos) { pos->lx = pos->lson->lx; pos->rx = pos->rson->rx; pos->x = max(pos->lson->x,pos->rson->x); if(pos->lx == pos->lson->len) pos->lx += pos->rson->lx; if(pos->rx == pos->rson->len) pos->rx += pos->lson->rx; pos->x = max(pos->x,pos->lson->rx+pos->rson->lx); } void pushdown(segtree *pos) { if(!pos->lson) pos->lson = newlson(pos); if(!pos->rson) pos->rson = newrson(pos); if(pos->lazy != -1) { pos->lson->lazy = pos->lazy; pos->rson->lazy = pos->lazy; pos->lson->x = pos->lson->lx = pos->lson->rx = pos->lazy*pos->lson->len; pos->rson->x = pos->rson->lx = pos->rson->rx = pos->lazy*pos->rson->len; pos->lazy = -1; } } void update(segtree *pos,int l,int r,int x) { if(r < pos->l || pos->r < l) return; if(l <= pos->l && pos->r <= r) { pos->x = pos->lx = pos->rx = pos->len*x; pos->lazy = x; return; } pushdown(pos); update(pos->lson,l,r,x); update(pos->rson,l,r,x); pushup(pos); } int getl(segtree *pos,int x) { if(pos->x < x) return 2e9;; if(pos->lx >= x) return pos->l; pushdown(pos); int minn = 2e9; if(pos->lson->rx+pos->rson->lx >= x) minn = pos->lson->r-pos->lson->rx+1; minn = min(minn,getl(pos->lson,x)); minn = min(minn,getl(pos->rson,x)); return minn; } int main() { while(~scanf("%d%d",&n,&q)) { set<int> s; map<int,int> mp; cnt = 0; root = newnode(1,n); while(q--) { char ss[20]; int x; scanf("%s",ss); if(ss[0] == 'm') { sscanf(ss,"malloc(%d)",&x); int t = getl(root,x); if(t == 2e9) printf("0\n"); else { printf("%d\n",t); update(root,t,t+x-1,0); s.insert(t); mp[t] = t+x-1; } } else { sscanf(ss,"free(%d)",&x); auto it = s.lower_bound(x); if(it == s.end() || *it != x) continue; update(root,*it,mp[*it],1); s.erase(it); } } } return 0; }
1066.a^b%c = a^(b%phi[c]+phi[c])%c。
#include<bits/stdc++.h> #define LL long long #define MOD 1000000007 using namespace std; LL a,b,n; LL PowerMod(LL a, LL b, LL c) { LL ans = 1; a = a % c; while(b) { if(b&1) ans = (ans*a)%c; b = b>>1; a = (a*a)%c; } return ans; } int main() { int T; cin >> T; while(T--) { cin >> a >> n >> b; int ans = b; for(int i = 2;i <= n;i++) { b = (b*b+MOD-2)%(MOD-1); ans = ans*b%(MOD-1); } cout << PowerMod(a,ans,MOD) << endl; } return 0; }
1067.dp[i]表示i个人的方案数,更新每个dp[i]时,枚举i的所有约数x,对于每一个x,可以有A(n-1,x-1)的情况的环,再根据乘法原理,乘上dp[i-x]。
#include<bits/stdc++.h> #define MOD 1000000007 using namespace std; int n,k,cnt; long long dp[20005],mul[20005],inv[20005],fac[20005]; long long qpower(long long a, long long b, long long c) { long long ans = 1; a = a%c; while(b) { if(b%2) ans = ans*a%c; a = a*a%c; b /= 2; } return ans; } int main() { ios::sync_with_stdio(0); mul[0] = 1; mul[1] = 1; inv[0] = 1; inv[1] = 1; for(int i = 2;i <= 20000;i++) mul[i] = mul[i-1]*i%MOD; for(int i = 2;i <= 20000;i++) inv[i] = inv[i-1]*qpower(i,MOD-2,MOD)%MOD; int T; scanf("%d",&T); while(T--) { scanf("%d%d",&n,&k); cnt = 0; int endd = sqrt(k+0.1); for(int i = 1;i <= endd;i++) { if(k%i == 0) { fac[++cnt] = i; if(k/i != i) fac[++cnt] = k/i; } } sort(fac+1,fac+cnt+1); memset(dp,0,sizeof(dp)); dp[0] = 1; for(int i = 1;i <= n;i++) { for(int j = 1;j <= cnt && fac[j] <= i;j++) dp[i] = (dp[i]+dp[i-fac[j]]*mul[i-1]%MOD*inv[i-fac[j]])%MOD; } printf("%lld\n",dp[n]); } return 0; }
1068.二分答案,根据单调性O(n)判断。
#include<bits/stdc++.h> #define LL long long using namespace std; LL a[10005],b[10005]; int n,m,k; int f(LL x) { int ans = 0,now = m; for(int i = 1;i <= n;i++) { while(now) { if(a[i]*b[now] > x) now--; else break; } ans += now; } return n*m-ans; } int main() { int T; cin >> T; while(T--) { cin >> n >> m >> k; k--; for(int i = 1;i <= n;i++) cin >> a[i]; for(int i = 1;i <= m;i++) cin >> b[i]; sort(a+1,a+1+n); sort(b+1,b+1+m); LL l = a[1]*b[1],r = a[n]*b[m]; while(l < r) { LL mid = (l+r)/2; int t = f(mid); if(t <= k) r = mid; else l = mid+1; } cout << l << endl; } return 0; }
1069.建一个虚点连接所有人,再连接人和人之间的关系,求最小生成树。
#include<bits/stdc++.h> using namespace std; struct line { int to,w; line(int a,int b):to(a),w(b){} friend bool operator<(line X,line Y) { return X.w > Y.w; } }; int n,m,k,x,dis[20005],vis[20005]; vector<line> v[20005]; int prim() { memset(vis,0,sizeof(vis)); memset(dis,0x3f,sizeof(dis)); int ans = 0,cnt = 0; priority_queue<line> q; q.push(line(0,0)); int endd = n+m; while(cnt <= endd && !q.empty()) { while(!q.empty() && vis[q.top().to]) q.pop(); ans += q.top().w; int now = q.top().to; vis[now] = 1; cnt++; for(int i = 0;i < v[now].size();i++) { if(vis[v[now][i].to]) continue; if(dis[v[now][i].to] <= v[now][i].w) continue; dis[v[now][i].to] = v[now][i].w; q.push(line(v[now][i].to,v[now][i].w)); } } return ans; } int main() { int T; cin >> T; while(T--) { cin >> m >> n >> k >> x; int endd = n+m; for(int i = 0;i <= endd;i++) v[i].clear(); for(int i = 1;i <= endd;i++) v[0].push_back(line(i,k)); while(x--) { int a,b,c; cin >> a >> b >> c; a += 1; b += m+1; c = k-c; v[a].push_back(line(b,c)); v[b].push_back(line(a,c)); } cout << prim() << endl; } return 0; }
1070.树形dp。
#include<bits/stdc++.h> using namespace std; int dp[105][105],n,m; vector<int> v[105]; void dfs(int pos,int pre) { for(int i = 0;i < v[pos].size();i++) { if(v[pos][i] == pre) continue; int x = v[pos][i]; dfs(x,pos); for(int j = m;j > 1;j--) { for(int k = 1;k <= j;k++) { dp[pos][j] = max(dp[pos][j],dp[x][j-k]+dp[pos][k]); } } } } int main() { int T; cin >> T; while(T--) { cin >> n >> m; memset(dp,0,sizeof(dp)); for(int i = 0;i < n;i++) v[i].clear(); for(int i = 0;i < n;i++) cin >> dp[i][1]; for(int i = 1;i < n;i++) { int a,b; cin >> a >> b; v[a].push_back(b); v[b].push_back(a); } dfs(0,-1); int ans = 0; for(int i = 0;i < n;i++) ans = max(ans,dp[i][m]); cout << ans << endl; } return 0; }
1071.枚举长宽。
#include<bits/stdc++.h> using namespace std; int n,m; int main() { int T; cin >> T; while(T--) { cin >> n >> m; int ans =0; for(int i = 1;i <= n;i++) { for(int j = 1;j <= m;j++) ans += i*j; } cout << ans << endl; } return 0; }
1072.求关键边的数量,即强连通分量-1,tarjan模版。
#include<bits/stdc++.h> using namespace std; int n,m,dfn[10005],low[10005],num,cnt; vector<int> v[10005]; void tarjan(int pos,int pre) { dfn[pos] = low[pos] = ++num; for(int i = 0;i < v[pos].size();i++) { int x = v[pos][i]; if(x == pre) continue; if(dfn[x] == 0) { tarjan(x,pos); low[pos] = min(low[pos],low[x]); if(dfn[pos] < low[x]) cnt++; } else low[pos] = min(low[pos],dfn[x]); } } int main() { int T; cin >> T; while(T--) { num = 0; cnt = 0; memset(dfn,0,sizeof(dfn)); memset(low,0,sizeof(low)); cin >> n >> m; for(int i = 0;i < n;i++) v[i].clear(); while(m--) { int x,y; cin >> x >> y; v[x].push_back(y); v[y].push_back(x); } tarjan(0,-1); cout << cnt << endl; } return 0; }
1073.容量为sum/2的01背包,先判断奇偶。
#include<bits/stdc++.h> using namespace std; int n,w[1005],dp[5005]; int main() { int T; cin >> T; while(T--) { memset(dp,0,sizeof(dp)); cin >> n; int sum = 0; for(int i = 1;i <= n;i++) { cin >> w[i]; sum += w[i]; } if(sum&1) { cout << "No" << endl; continue; } int endd = sum/2; for(int i = 1;i <= n;i++) { for(int j = endd;j >= w[i];j--) dp[j] = max(dp[j],dp[j-w[i]]+w[i]); } if(dp[endd] == endd) cout << "Yes" << endl; else cout << "No" << endl; } return 0; }
*1074.待补。
*1075.待补。
1076.类似于三进制,输入数据中有空行,用gets会出错。
#include<bits/stdc++.h> using namespace std; char s[105]; int f(char x) { if(x == '1') return 1; if(x == '3') return 2; if(x == '5') return 3; } int main() { while(~scanf("%s",s)) { int len = strlen(s); long long ans = 0; for(int i = 0;i < len;i++) ans = ans*3+f(s[i]); printf("%lld\n",ans); } return 0; }
1077.循环节仅看分母,先把分母2,5除完后为m,求欧拉数,循环节长度为欧拉数约数中最小数x的使10^x%m == 1的值。
#include<bits/stdc++.h> #define LL long long using namespace std; LL PowerMod(LL a, LL b, LL c) { LL ans = 1; a = a % c; while(b) { if(b&1) ans = (ans*a)%c; b = b>>1; a = (a*a)%c; } return ans; } int euler(int n) { int res = n,a = n; for(int i = 2;i*i <= a;i++) { if(a%i == 0) { res = res/i*(i-1); while(a%i == 0) a /= i; } } if(a > 1) res = res/a*(a-1); return res; } int gcd(int a,int b) { return b?gcd(b,a%b):a; } int main() { int p,q; while(cin >> p >> q) { q /= gcd(p,q); while(q%2 == 0) q /= 2; while(q%5 == 0) q /= 5; if(q == 1) { cout << 0 << endl; continue; } int x = euler(q),now = 1; int xx = sqrt(x),flag = 0; for(int i = 1;i <= xx;i++) { if(x%i) continue; if(PowerMod(10,i,q) == 1) { cout << i << endl; flag = 1; break; } } if(flag) continue; for(int i = xx;i >= 1;i--) { if(x%i) continue; if(PowerMod(10,x/i,q) == 1) { cout << x/i << endl; break; } } } return 0; }
1078.分层图最短路模版,建k+1层图。
#include<bits/stdc++.h> #define INF 0x3f3f3f3f using namespace std; struct edge { int to,cost; friend bool operator>(edge x,edge y) { return x.cost > y.cost; } }e; vector<edge> v[11005]; int n,m,k,a[1005][1005],dis[11005],vis[11005]; priority_queue< edge,vector<edge>,greater<edge> > q; int dij() { while(!q.empty()) q.pop(); memset(dis,0x3f,sizeof(dis)); memset(vis,0,sizeof(vis)); dis[1] = 0; e.to = 1; e.cost = 0; q.push(e); while(!q.empty()) { int now = q.top().to,cost = q.top().cost; if(now == (k+1)*n) return dis[(k+1)*n]; q.pop(); if(vis[now]) continue; vis[now] = 1; for(int i = 0;i < v[now].size();i++) { e = v[now][i]; if(e.cost+dis[now] < dis[e.to]) { dis[e.to] = e.cost+dis[now]; e.cost = dis[e.to]; q.push(e); } } } } int main() { while(cin >> n >> m >> k) { for(int i = 1;i <= 11000;i++) v[i].clear(); memset(a,0x3f,sizeof(a)); for(int i = 1;i <= m;i++) { int u,v,w; cin >> u >> v >> w; a[u][v] = min(a[u][v],w); a[v][u] = min(a[v][u],w); } for(int i = 1;i <= n;i++) { for(int j = 1;j <= n;j++) { if(i == j || a[i][j] == INF) continue; for(int l = 0;l <= k;l++) { e.to = l*n+j; e.cost = a[i][j]; v[l*n+i].push_back(e); if(l != k) { e.to = (l+1)*n+j; e.cost = 0; v[l*n+i].push_back(e); } } } } cout << dij() << endl; } return 0; }
1079.枚举两个数,之后的处理类似于最大连续子序列和。
#include<bits/stdc++.h> using namespace std; int a[100005],n,m,has[15]; int main() { int T; cin >> T; while(T--) { memset(has,0,sizeof(has)); cin >> n >> m; int cnt = 0; for(int i = 1;i <= n;i++) { cin >> a[i]; if(!has[a[i]]) has[a[i]] = 1; } int ans = 0; for(int i = 1;i <= m;i++) { for(int j = 1;j <= m;j++) { if(i == j) continue; if(!has[i] || !has[j]) continue; int sum = 0,flag = 0; for(int k = 1;k <= n;k++) { if(a[k] == i) sum++; else if(a[k] == j) { sum--; flag = 1; } if(sum < 0) { sum = 0; flag = 0; } if(flag) ans = max(ans,sum); else ans = max(ans,sum-1); } } } cout << ans << endl; } return 0; }
1080.规律。
#include<bits/stdc++.h> using namespace std; int main() { int n; while(cin >> n) cout << n*n*4 << endl; return 0; }
1081.判断两个范围是否有交集。
#include<bits/stdc++.h> using namespace std; long long a1,a2,b1,b2,c1,c2,d1,d2; int main() { while(cin >> a1 >> a2 >> b1 >> b2 >> c1 >> c2 >> d1 >> d2) { long long x1 = a1*d1,x2 = a2*d2,y1 = b1*c1,y2 = b2*c2; if(x1 > y2 || x2 < y1) cout << "NO" << endl; else cout << "YES" << endl; } return 0; }
1082.若场数最多的人比其余的和要大,则ans为其余的和,否则ans为sum/2。
#include<bits/stdc++.h> using namespace std; int n; int main() { int T; cin >> T; while(T--) { long long maxx = 0,sum = 0,temp; cin >> n; while(n--) { cin >> temp; maxx = max(maxx,temp); sum += temp; } cout << min(sum/2,sum-maxx) << endl; } return 0; }
1083.从左到右扫一遍,记录左括号个数,有右括号时更新答案就可以了。
#include<bits/stdc++.h> using namespace std; int main() { int T; string s; cin >> T; while(T--) { cin >> s; int len = s.length(),cnt = 0,ans = 0; for(int i = 0;i < len;i++) { if(s[i] == '(') cnt++; else if(cnt) { cnt--; ans += 2; } } cout << ans << endl; } return 0; }
1084.暴力搜索,不会超时。
#include<bits/stdc++.h> using namespace std; int n,u,v,vis[15],sco[15],ans,k; vector<int> pre[15]; void dfs(int x,int sum) { if(x == 0) { ans = max(ans,sum); return; } for(int i = 1;i <= 10;i++) { if(vis[i]) continue; int flag = 1; for(int j = 0;j < pre[i].size();j++) { if(!vis[pre[i][j]]) { flag = 0; break; } } if(!flag) continue; vis[i] = 1; dfs(x-1,sum+sco[i]); vis[i] = 0; } } int main() { ios::sync_with_stdio(0); while(cin >> n) { memset(vis,0,sizeof(vis)); for(int i = 1;i <= 10;i++) pre[i].clear(); while(n--) { cin >> u >> v; pre[v].push_back(u); } for(int i = 1;i <= 10;i++) cin >> sco[i]; cin >> k; ans = 0; dfs(k/3,0); if(ans >= 60) cout << ans << endl; else cout << "I chose to die" << endl; } return 0; }
*1085.待补。
1086.简单模拟。
#include<bits/stdc++.h> using namespace std; int n,m,h,op[1005],a[1005],hh[1005]; int main() { int T; cin >> T; while(T--) { memset(a,-1,sizeof(a)); cin >> n; for(int i = 0;i < n;i++) cin >> op[i]; cin >> m; for(int i = 1;i <= m;i++) cin >> hh[i]; int pos; for(int i = 1;i <= m;i++) { cin >> pos; if(pos <= n) a[pos] = hh[i]; } cin >> h; int flag = 1,now = 0; while(now < n) { if(op[now] == 1) h++; else if(op[now] == 0) h--; if(h == 0 || a[now] != -1 && h >= a[now]) { flag = 0; break; } now++; } if(flag) cout << "V8Orz" << endl; else cout << now << endl; } return 0; }
1087.贪心单位体积的价值。
#include<bits/stdc++.h> using namespace std; int n,w,V; struct aa { int v; double a; }a[1005]; bool cmp(aa x,aa y) { return x.a < y.a; } int main() { int T; cin >> T; while(T--) { cin >> n; for(int i = 1;i <= n;i++) { cin >> a[i].v >> w; a[i].a = (double)w/a[i].v; } cin >> V; sort(a+1,a+1+n,cmp); int now = n; double ans = 0; while(V && now >= 1) { if(V > a[now].v) { ans += a[now].a*a[now].v; V -= a[now].v; now--; } else { ans += V*a[now].a; break; } } cout << fixed << setprecision(4) << ans << endl; } return 0; }
1088.按字典序从大到小排序。
#include<bits/stdc++.h> using namespace std; string s[100005]; int n; bool cmp(string x,string y) { string X = x+y,Y = y+x; return X > Y; } int main() { while(cin >> n) { for(int i = 1;i <= n;i++) cin >> s[i]; sort(s+1,s+1+n,cmp); for(int i = 1;i <= n;i++) cout << s[i]; cout << endl; } return 0; }
1089.时间顺序的bfs,注意多个水珠同时到一点的情况。
#include<bits/stdc++.h> using namespace std; int n,m,nn,tt,a[105][2],sta[105][105],t[105][105],dir[4][2] = {-1,0,0,-1,1,0,0,1}; struct water { int x,y,d,t; water(int _x,int _y,int _d,int _t):x(_x),y(_y),d(_d),t(_t){}; }; void bfs(int x,int y) { queue<water> q; q.push(water(x,y,0,1)); q.push(water(x,y,1,1)); q.push(water(x,y,2,1)); q.push(water(x,y,3,1)); while(!q.empty()) { water temp = q.front(); q.pop(); if(temp.t > tt) return; int xx = temp.x+dir[temp.d][0],yy = temp.y+dir[temp.d][1]; if(xx < 1 || xx > n || yy < 1 || yy > m) continue; if(t[xx][yy] == temp.t) continue; if(sta[xx][yy] == 0) q.push(water(xx,yy,temp.d,temp.t+1)); else if(sta[xx][yy] == 4) { sta[xx][yy] = 0; t[xx][yy] = temp.t; q.push(water(xx,yy,0,temp.t+1)); q.push(water(xx,yy,1,temp.t+1)); q.push(water(xx,yy,2,temp.t+1)); q.push(water(xx,yy,3,temp.t+1)); } else sta[xx][yy]++; } } int main() { while(cin >> n >> m >> nn >> tt) { memset(sta,0,sizeof(sta)); memset(t,0,sizeof(t)); for(int i = 1;i <= nn;i++) { int x; cin >> a[i][0] >> a[i][1] >> x; sta[a[i][0]][a[i][1]] = x; } int x,y; cin >> x >> y; bfs(x,y); for(int i = 1;i <= nn;i++) { if(t[a[i][0]][a[i][1]] == 0) cout << 1 << " " << sta[a[i][0]][a[i][1]] << endl; else cout << 0 << " " << t[a[i][0]][a[i][1]] << endl; } } return 0; }
1090.树形dp。
#include<bits/stdc++.h> using namespace std; struct line { int next,w; }l; vector<line> v[10005]; int n; int dfs(int x) { int sum = 0; for(int i = 0;i < v[x].size();i++) sum = max(sum,dfs(v[x][i].next)+v[x][i].w); return sum; } int main() { int T; cin >> T; while(T--) { cin >> n; for(int i = 1;i <= 10000;i++) v[i].clear(); for(int i = 1;i <= n;i++) { int u; cin >> u >> l.next >> l.w; v[u].push_back(l); } cout << dfs(1) << endl; } return 0; }
1091.按结束时间排序,贪心。
#include<bits/stdc++.h> using namespace std; struct vedio { int l,r; }a[1005]; int n; bool cmp(vedio x,vedio y) { return x.r < y.r; } int main() { while(cin >> n && n) { for(int i = 1;i <= n;i++) cin >> a[i].l >> a[i].r; sort(a+1,a+1+n,cmp); int ans = 1,time = a[1].r,now = 2; for(;now <= n;now++) { if(time > a[now].l) continue; time = a[now].r; ans++; } cout << ans << endl; } return 0; }
1092.模拟,每次移动后,不断下落,消去,直到不变化为止。
#include<bits/stdc++.h> using namespace std; int n,a[10][10],ans[10][10]; int fmove() { int flag = 0; for(int i = 0;i < 5;i++) { for(int j = 0;j < 7;j++) { if(!a[i][j]) continue; int t = j; while(t > 0 && a[i][t-1] == 0) { flag = 1; swap(a[i][t],a[i][t-1]); t--; } } } return flag; } void fdel() { memset(ans,0,sizeof(ans)); for(int i = 0;i < 5;i++) { int l = 0,cnt = 1; for(int j = 1;j <= 7;j++) { if(a[i][j] == a[i][j-1]) cnt++; else { if(cnt >= 3) { for(int k = l;k < j;k++) ans[i][k] = 1; } l = j; cnt = 1; } } } for(int j = 0;j < 7;j++) { int l = 0,cnt = 1; for(int i = 1;i <= 5;i++) { if(a[i][j] == a[i-1][j]) cnt++; else { if(cnt >= 3) { for(int k = l;k < i;k++) ans[k][j] = 1; } l = i; cnt = 1; } } } for(int i = 0;i < 5;i++) { for(int j = 0;j < 7;j++) { if(ans[i][j]) a[i][j] = 0; } } } int main() { while(~scanf("%d",&n)) { int flag = 0; memset(a,0,sizeof(a)); for(int i = 0;i < 5;i++) { for(int j = 0;j < 8;j++) { scanf("%d",&a[i][j]); if(!a[i][j]) break; } } while(n--) { int x,y,d; scanf("%d%d%d",&x,&y,&d); if(!a[x][y] || d+x > 4 || d+x < 0) { printf("Runtime Error\n"); flag = 1; } else { swap(a[x][y],a[x+d][y]); fmove(); fdel(); while(fmove()) fdel(); } } if(flag) continue; for(int i = 0;i < 5;i++) { for(int j = 0;j < 7;j++) { if(a[i][j]) flag = 1; } } if(!flag) printf("Accepted\n"); else printf("Wrong Answer\n"); } return 0; }
1093.确定两个区间,二分答案。
#include<bits/stdc++.h> using namespace std; const double eps=0.0001; double a,b,c,d; double ans[5]; int sum; inline double calc(double x) { return a*x*x*x+b*x*x+c*x+d; } void find(double l,double r) { while(1) { double mid = (l+r)/2; if(abs(calc(mid)) < eps) { ans[++sum] = mid; return; } if(calc(mid)*calc(l) < 0) r = mid; else l = mid; } } int main() { while(cin >> a >> b >> c >> d) { sum = 0; for(int i=-101;i<=101;i++) { double tmp1 = calc(i),tmp2 = calc(i+1); if(abs(tmp1) < eps) ans[++sum] = i; else if(abs(tmp2) < eps) { ans[++sum] = i+1; i++; } else if(tmp1*tmp2 < 0) find(i,i+1); if(sum == 3) break; } sort(ans+1,ans+4); cout << fixed << setprecision(2) << ans[1] << " " << ans[2] << " " << ans[3] << endl; } return 0; }
1094.递归输出。
#include<bits/stdc++.h> using namespace std; int n; void printff(int x) { if(x == 1) { cout <<"2(0)"; return; } if(x == 2) { cout << "2"; return; } int sum = 1,b = -1; while(sum <= x) { sum *= 2; b++; } if(sum/2 < x) { if(sum/2 == 2) { cout << "2+"; printff(x-sum/2); } else { cout << "2("; printff(b); cout << ")+"; printff(x-sum/2); } } else { cout << "2("; printff(b); cout << ")"; } } int main() { ios::sync_with_stdio(0); while(cin >> n) { printff(n); cout << endl; } return 0; }
1095.暴力搜索,不会超时。
#include<bits/stdc++.h> using namespace std; int vis[15],a[15],n,k,ans; void dfs(int num,int v) { if(num == n) { if(abs(v-a[1]) <= k) ans++; return; } for(int i = 2;i <= n;i++) { if(vis[i]) continue; if(abs(v-a[i]) > k) continue; vis[i] = 1; dfs(num+1,a[i]); vis[i] = 0; } } int main() { ios::sync_with_stdio(0); while(cin >> n >> k) { memset(vis,0,sizeof(vis)); ans = 0; for(int i = 1;i <= n;i++) cin >> a[i]; dfs(1,a[1]); cout << ans << endl; } return 0; }
1096.dp[i][j]表示i拆分成最大为j的数。
#include<bits/stdc++.h> using namespace std; int dp[85][85],n; int main() { ios::sync_with_stdio(0); for(int i = 1;i <= 80;i++) { dp[i][1] = 1; dp[1][i] = 1; } for(int i = 2;i <= 80;i++) { for(int j = 2;j <= 80;j++) { if(i == j) dp[i][j] = dp[i][j-1]+1; else if(i < j) dp[i][j] = dp[i][j-1]; else dp[i][j] = dp[i-j][j]+dp[i][j-1]; } } while(cin >> n) cout << dp[n][n]-1 << endl; return 0; }
1097.dp[i] = dp[i-1]+dp[i-2]+dp[i-3]。
#include<bits/stdc++.h> using namespace std; int n; long long dp[75]; int main() { dp[1] = 1; dp[2] = 2; dp[3] = 4; for(int i = 4;i <= 70;i++) dp[i] = dp[i-1]+dp[i-2]+dp[i-3]; while(cin >> n) cout << dp[n] << endl; return 0; }
1098.求欧拉函数模版。
#include<bits/stdc++.h> using namespace std; int n; int euler(int n) { int res = n,a = n; for(int i = 2;i*i <= a;i++) { if(a%i == 0) { res = res/i*(i-1); while(a%i == 0) a /= i; } } if(a > 1) res = res/a*(a-1); return res; } int main() { ios::sync_with_stdio(0); while(cin >> n) cout << euler(n) << endl; return 0; }
1099.双指针,线性扫一遍。
#include<bits/stdc++.h> using namespace std; int a[100005],n,k; int main() { ios::sync_with_stdio(0); int T; cin >> T; while(T--) { cin >> n >> k; for(int i = 1;i <= n;i++) cin >> a[i]; int l = 0,now = 0; long long ans = 0; for(int i = 1;i <= n;i++) { now += a[i]; while(now > k) now -= a[++l]; ans += i-l; } cout << ans << endl; } return 0; }
1100.即求最大矩阵面积,单调栈模版。
#include<bits/stdc++.h> using namespace std; int n; stack<int> s; long long a[100005],b[100005]; int main() { ios::sync_with_stdio(0); while(cin >> n) { while(!s.empty()) s.pop(); long long ans = 0; b[1] = 0; for(int i = 1;i <= n;i++) cin >> a[i]; for(int i = 2;i <= n;i++) { cin >> b[i]; b[i] += b[i-1]; } a[n+1] = 0; for(int i = 1;i <= n+1;i++) { while(!s.empty() && a[s.top()] > a[i]) { int temp = s.top(); s.pop(); long long len = s.empty()?b[i-1]:b[i-1]-b[s.top()+1]; ans = max(ans,len*a[temp]); } s.push(i); } cout << ans << endl; } return 0; }
1101.模拟进制加法。
#include<bits/stdc++.h> using namespace std; int k,n; int main() { ios::sync_with_stdio(0); while(cin >> k >> n) { long long ans = 0,temp = 1; while(n) { ans += temp*(n%2); n /= 2; temp *= k; } cout << ans << endl; } return 0; }
1102.dp[i][j]表示i个钩子,j个灯笼的方案数,先求一个钩子的情况,再O(n^3)求多个钩子的情况。
#include<bits/stdc++.h> #define MOD 1000000007 using namespace std; int n,m; long long dp[205][205]; int main() { ios::sync_with_stdio(0); for(int i = 1;i <= 200;i++) dp[i][0] = 1; for(int i = 1;i <= 200;i++) { for(int j = 0;j < i;j++) dp[1][i] = (dp[1][i]+dp[1][j]*dp[1][i-j-1])%MOD; } for(int i = 2;i <= 200;i++) { for(int j = 1;j <= 200;j++) { for(int k = 0;k <= j;k++) dp[i][j] = (dp[i][j]+dp[i-1][k]*dp[1][j-k])%MOD; } } while(cin >> n >> m) cout << dp[n][m] << endl; return 0; }
*1103.待补。
1104.dfs两侧点的个数,相乘。
#include<bits/stdc++.h> using namespace std; int n,m,from[1005],to[1005]; vector<int> v[1005]; int dfs(int s,int t) { int ans = 1; for(int i = 0;i < v[s].size();i++) { if(v[s][i] == t) continue; ans += dfs(v[s][i],s); } return ans; } int main() { ios::sync_with_stdio(0); int T; cin >> T; while(T--) { cin >> n >> m; for(int i = 1;i <= n;i++) v[i].clear(); for(int i = 1;i < n;i++) { int a,b; cin >> a >> b; from[i] = a; to[i] = b; v[a].push_back(b); v[b].push_back(a); } for(int i = 1;i <= m;i++) { int x; cin >> x; int t = dfs(to[x],from[x]); cout << t*(n-t) << endl; } } return 0; }
1105.约数个数。
#include<bits/stdc++.h> using namespace std; int n; int main() { int T; cin >> T; while(T--) { cin >> n; int ans = 0; for(int i = 1;i <= sqrt(n+0.1);i++) { if(n%i == 0) { if(i == n/i) ans++; else ans += 2; } } cout << ans << endl; } return 0; }
1106.求n!/(每个数字个数)!,先统计个数,然后对于每种个数分解质因数,得到最后剩余的所有质因数和其个数,再计算答案。
#include<bits/stdc++.h> #define MAXN 1000000 using namespace std; int n,a[1005]; int cnt,prime[MAXN+1] = {0},mi[MAXN+1],vis[MAXN+1] = {0}; long long b[1000005]; void getprime() { cnt = 0; for(int i = 2;i <= MAXN;i++) { if(!vis[i]) { prime[++cnt] = i; mi[i] = i; } for(int j = 1;j <= cnt && (long long)i*prime[j] <= MAXN;j++) { vis[prime[j]*i] = 1; mi[prime[j]*i] = prime[j]; if(!(i%prime[j])) break; } } } int main() { ios::sync_with_stdio(0); getprime(); while(~scanf("%d",&n)) { memset(a,0,sizeof(a)); memset(b,0,sizeof(b)); for(int i = 1;i <= n;i++) { int x; scanf("%d",&x); a[x]++; } for(int i = 2;i <= n;i++) b[i]++; for(int i = 0;i <= 1000;i++) { for(int j = 2;j <= a[i];j++) b[j]--; } for(int i = 1000000;i >= 2;i--) { if(b[i] == 0) continue; int cnt = b[i],t = i; b[i] = 0; while(t != 1) { b[mi[t]] += cnt; t /= mi[t]; } } long long now = 1; int ok = 1; for(int i = 2;i <= 1000000;i++) { while(b[i]--) { if(5e18/i > now && now*i <= 1e18) now *= i; else ok = 0; } } if(ok) cout << now << endl; else cout << "Look, shability!" << endl; } return 0; }
1107.按x排序好后,按y求最长上升子序列。
#include<bits/stdc++.h> using namespace std; struct point { int x,y; }a[100005]; int b[100005],n; bool cmp(point X,point Y) { if(X.x == Y.x) return X.y > Y.y; return X.x < Y.x; } int LIS() { int len = 1,j; b[1] = a[1].y; for(int i = 2;i <= n;i++) { if(a[i].y > b[len]) j = ++len; else j = lower_bound(b+1,b+1+len,a[i].y)-b; b[j] = a[i].y; } return len; } int main() { ios::sync_with_stdio(0); while(cin >> n) { for(int i = 1;i <= n;i++) cin >> a[i].x; for(int i = 1;i <= n;i++) cin >> a[i].y; sort(a+1,a+1+n,cmp); cout << LIS() << endl; } return 0; }
1108.打表,前缀和。
#include<bits/stdc++.h> using namespace std; int x,y,a[1000005] = {0}; int main() { a[0] = a[1] = 0; for(int i = 2;i <= 1000000;i++) { if(i%2) a[i] = a[i-1]+1; else a[i] = a[i/2]+1; } for(int i = 2;i <= 1000000;i++) a[i] += a[i-1]; while(cin >> x >> y) cout << a[y]-a[x-1] << endl; return 0; }
1109.dp[i] = dp[i-1]+dp[i-2]+dp[i-3]。
#include<bits/stdc++.h> using namespace std; int n,a[1000005]; int main() { ios::sync_with_stdio(0); a[1] = 1; a[2] = 2; a[3] = 4; for(int i = 4;i <= 1000000;i++) a[i] = (a[i-1]+a[i-2]+a[i-3])%10007; while(cin >> n) cout << a[n] << endl; return 0; }
1111.f(n)=f(n-1)+f(n-2)+n-2推出f(n)=3*f(n-1)-2*f(n-2)-f(n-3)+f(n-4),矩阵快速幂。
#include<bits/stdc++.h> #define MOD 1000000007 using namespace std; int n,anss[6] = {0,0,0,1,3,7}; struct matrix { long long m[4][4]; }; matrix ans = { 1,0,0,0, 0,1,0,0, 0,0,1,0, 0,0,0,1,}; matrix base = { 3,1,0,0, MOD-2,0,1,0, MOD-1,0,0,1, 1,0,0,0,}; matrix mul(matrix a, matrix b) { matrix tmp; for(int i = 0; i < 4;i++) { for(int j = 0; j < 4;j++) { tmp.m[i][j] = 0; for(int k = 0; k < 4;k++) tmp.m[i][j] = (tmp.m[i][j]+a.m[i][k]*b.m[k][j])%MOD; } } return tmp; } long long fast_mod(int n) { matrix x = ans,y = base; while(n) { if(n & 1) { x = mul(x,y); } y = mul(y,y); n >>= 1; } return (anss[5]*x.m[0][0]+anss[4]*x.m[1][0]+anss[3]*x.m[2][0]+anss[2]*x.m[3][0])%MOD; } int main() { ios::sync_with_stdio(0); while(cin >> n) { if(n <= 5) cout << anss[n] << endl; else cout << fast_mod(n-5) << endl; } }
1112.dp[i][j]表示i个人j派的方案数。
#include<bits/stdc++.h> #define MOD 1000000007 using namespace std; long long dp[1005][1005] = {0},ans[1005] = {0}; int n; int main() { ios::sync_with_stdio(0); dp[1][1] = 1; for(int i = 2;i <= 1000;i++) { for(int j = 1;j <= i;j++) dp[i][j] = (dp[i-1][j-1]+dp[i-1][j]*j)%MOD; } for(int i = 1;i <= 1000;i++) { for(int j = 1;j <= i;j++) ans[i] = (ans[i]+dp[i][j])%MOD; } while(cin >> n) cout << ans[n] << endl; return 0; }
1113.dp[i][j]表示前i位起余数为j的个数。
#include<bits/stdc++.h> using namespace std; string s; int k; long long dp[100005][55]; int main() { ios::sync_with_stdio(0); while(cin >> s >> k) { memset(dp,0,sizeof(dp)); dp[0][(s[0]-'0')%k]++; for(int i = 1;i < s.length();i++) { for(int j = 0;j < k;j++) dp[i][(j*10+s[i]-'0')%k] += dp[i-1][j]; dp[i][(s[i]-'0')%k]++; } long long ans = 0; for(int i = 0;i < s.length();i++) ans += dp[i][0]; cout << ans << endl; } return 0; }
1114.先离线,按所有点的和k1,k2的大小排序,再树状数组维护一下。
#include<bits/stdc++.h> using namespace std; struct arr { int o,x,pos,l,r; }a[300005]; int n,m,tree[300005] = {0},ans1[100005],ans2[100005]; bool cmp(arr X,arr Y) { if(X.x == Y.x) return X.o < Y.o; return X.x < Y.x; } inline int lowbit(int x) { return x & (-x); } void update(int pos,int x) { while(pos <= n) { tree[pos] += x; pos += lowbit(pos); } } int getsum(int pos) { int sum = 0; while(pos > 0) { sum += tree[pos]; pos -= lowbit(pos); } return sum; } int main() { while(~scanf("%d%d",&n,&m)) { memset(tree,0,sizeof(tree)); for(int i = 1;i <= n;i++) { scanf("%d",&a[i].x); a[i].pos = i; a[i].o = 1; } int cnt = n; for(int i = 1;i <= m;i++) { scanf("%d%d%d%d",&a[cnt+1].l,&a[cnt+1].r,&a[cnt+1].x,&a[cnt+2].x); a[cnt+1].o = 0; a[cnt+2].o = 2; a[cnt+1].pos = a[cnt+2].pos = i; a[cnt+2].l = a[cnt+1].l; a[cnt+2].r = a[cnt+1].r; cnt += 2; } sort(a+1,a+1+cnt,cmp); for(int i = 1;i <= cnt;i++) { if(a[i].o == 1) update(a[i].pos,1); else if(a[i].o == 0) ans1[a[i].pos] = getsum(a[i].r)-getsum(a[i].l-1); else ans2[a[i].pos] = getsum(a[i].r)-getsum(a[i].l-1); } for(int i = 1;i <= m;i++) printf("%d\n",ans2[i]-ans1[i]); } return 0; }
1115.x^n+y^n = (x^(n-1)+y^(n-1))*(x+y)-(x^(n-2)+y^(n-2))*x*y。
#include<bits/stdc++.h> #define MOD 1000000007 using namespace std; int a,b,n; long long ans[10005]; int main() { ios::sync_with_stdio(0); ans[0] = 2; while(cin >> a >> b >> n) { ans[1] = a; for(int i = 2;i <= n;i++) ans[i] = ((ans[i-1]*a-ans[i-2]*b%MOD)+MOD)%MOD; cout << ans[n] << endl; } return 0; }
1116.求n!/(每一个重要城市子树种的节点数)。
#include<bits/stdc++.h> #define MOD 1000000007 using namespace std; int n,m,ok[100005],a[100005]; vector<int> v[100005]; long long qpower(long long a,long long b,long long c) { long long ans = 1; a %= c; while(b) { if(b%2) ans = ans*a%c; a = a*a%c; b /= 2; } return ans; } void dfs(int now,int pre) { a[now] = 1; for(int i = 0;i < v[now].size();i++) { int t = v[now][i]; if(t == pre) continue; dfs(t,now); a[now] += a[t]; } } int main() { ios::sync_with_stdio(0); while(cin >> n >> m) { memset(ok,0,sizeof(ok)); for(int i = 1;i <= n;i++) v[i].clear(); for(int i = 1;i < n;i++) { int x,y; cin >> x >> y; v[x].push_back(y); v[y].push_back(x); } dfs(1,-1); long long ans = 1; for(int i = 1;i <= n;i++) ans = (ans*i)%MOD; for(int i = 1;i <= m;i++) { int x; cin >> x; if(ok[x]) continue; ans = (ans*qpower(a[x],MOD-2,MOD))%MOD; ok[x] = 1; } cout << ans << endl; } return 0; }
1117.状压dp。
#include<bits/stdc++.h> #define LL long long #define MOD 1000000007 using namespace std; int n,m; LL dp[105][1<<11]; vector<int> v[105]; LL dfs(int left,int sta) { if(dp[left][sta] != -1) return dp[left][sta]; if(left == 0) return !sta; dp[left][sta] = 0; for(int i = 0;i < v[left].size();i++) { dp[left][sta] = (dp[left][sta]+dfs(left-1,sta^v[left][i]))%MOD; } return dp[left][sta]; } int main() { while(~scanf("%d%d",&n,&m)) { memset(dp,-1,sizeof(dp)); for(int i = 1;i <= m;i++) v[i].clear(); for(int i = 1;i <= m;i++) { int t,endd = 1<<n; scanf("%d",&t); for(int j = 0;j < endd;j++) { int sum = 0; for(int k = 0;k < n;k++) { if(j&(1<<k)) sum++; } if(sum == t) v[i].push_back(j); } } int a = 0; for(int i = 0;i < n;i++) { int t; scanf("%d",&t); a |= (1<<i)*t; } printf("%lld\n",dfs(m,a)); } return 0; }
1118.暴力搜索边的组成顺序,每次判断只要延长边,判断是否正三角形。
#include<bits/stdc++.h> #define PI (atan(1)*4) using namespace std; int a[6],b[6],vis[6] = {0}; double ans; void dfs(int cnt) { if(cnt == 6) { if(b[0]+b[1]+b[3] == b[0]+b[2]+b[4] && b[0]+b[2]+b[4] == b[1]+b[2]+b[5]) { ans = sqrt(3)/4*((b[0]+b[2]+b[4])*(b[0]+b[2]+b[4])-b[0]*b[0]-b[1]*b[1]-b[2]*b[2]); } } for(int i = 0;i < 6;i++) { if(vis[i]) continue; b[cnt] = a[i]; vis[i] = 1; dfs(cnt+1); vis[i] = 0; } } int main() { ios::sync_with_stdio(false); while(cin >> a[0] >> a[1] >> a[2] >> a[3] >> a[4] >> a[5]) { ans = 0; dfs(0); if(ans > 1e-5) cout << fixed << setprecision(2) << ans << endl; else cout << 0 << endl; } return 0; }
1119.递增枚举最小公倍数。
#include<bits/stdc++.h> using namespace std; int a[1005],n,k; bool ok(int x) { int cnt = 0; for(int i = 1;i <= n;i++) { if(x%a[i] == 0) cnt++; } if(cnt >= k) return 1; return 0; } int main() { ios::sync_with_stdio(0); while(cin >> n >> k) { for(int i = 1;i <= n;i++) cin >> a[i]; int ans = 1; for(;ans <=1000;ans++) { if(ok(ans)) break; } if(ans <= 1000) cout << ans << endl; else cout << "Orz" << endl; } return 0; }
1120.贪心,时间后往前,大的先考虑,可以用优先队列优化一下。
#include<bits/stdc++.h> using namespace std; struct task { int t,v; }a[1005]; int n,vis[1005] = {0}; bool cmp(task x,task y) { return x.v > y.v; } int main() { ios::sync_with_stdio(0); cin >> n; int t = 0,sum = 0,ans = 0; for(int i = 1;i <= n;i++) { cin >> a[i].t; t = max(a[i].t,t); } for(int i = 1;i <= n;i++) { cin >> a[i].v; sum += a[i].v; } sort(a+1,a+1+n,cmp); for(int i = t;i >= 1;i--) { for(int j = 1;j <= n;j++) { if(!vis[j] && i <= a[j].t) { ans += a[j].v; vis[j] = 1; break; } } } cout << sum-ans << endl; return 0; }
1121.60个刚好超1e18,60之前直接递归算,60之后的用60的来算。
#include<bits/stdc++.h> using namespace std; long long a[65],n,k; int f(long long x,long long y) { if(x == 1) return 1; if(y <= a[x-1]) return f(x-1,y)^1; if(y == a[x-1]+1) return 1; return f(x-1,a[x]-y+1); } int main() { ios::sync_with_stdio(0); a[1] = 1; for(int i = 2;i <= 64;i++) a[i] = a[i-1]*2+1; while(cin >> n >> k) { int ans; if(n <= 60) ans = f(n,k); else { ans = f(60,k); if(n&1) ans ^= 1; } if(ans) cout << "srO" << endl; else cout << "Orz\n" << endl; } return 0; }
1123.二分查找。
#include<bits/stdc++.h> using namespace std; struct orz { int id,x; friend bool operator<(struct orz X,struct orz Y) { if(X.x == Y.x) return X.id < Y.id; return X.x < Y.x; } }a[100005],t; int n,m; int main() { ios::sync_with_stdio(0); t.id = 0; while(cin >> n >> m) { for(int i = 1;i <= n;i++) { cin >> a[i].x; a[i].id = i; } sort(a+1,a+1+n); int flag = 1; while(m--) { cin >> t.x; int ans = lower_bound(a+1,a+1+n,t)-a; if(flag) { if(ans > n) cout << -1; else cout << a[ans].id; flag = 0; } else { if(ans > n) cout << " -1"; else cout << " " << a[ans].id; } } cout << endl; } return 0; }
1124.找第一个可以替代的数,用后面最大且最后的数替代。
#include<bits/stdc++.h> using namespace std; char a[1005]; int main() { while(cin >> a) { int len = strlen(a),first = 0,last = 0,now = 0; while(now < len) { first = last = now; char maxx = a[now]; for(int i = len-1;i > now;i--) { if(a[i] > maxx) { maxx = a[i]; last = i; } } if(first != last) break; now++; } swap(a[first],a[last]); cout << a << endl; } return 0; }
1125.分成三个三角形,由面积判断。
#include<bits/stdc++.h> using namespace std; double f(double x1,double y1,double x2,double y2,double x3,double y3) { double a,b,c,p; a = sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2)); b = sqrt((x1-x3)*(x1-x3)+(y1-y3)*(y1-y3)); c = sqrt((x3-x2)*(x3-x2)+(y3-y2)*(y3-y2)); p = (a+b+c)/2; return sqrt(p*(p-a)*(p-b)*(p-c)); } int main() { double x1,x2,x3,y1,y2,y3,x,y; while(cin >> x1 >> y1 >> x2 >> y2 >> x3 >> y3 >> x >> y) { if(abs(f(x1,y1,x2,y2,x3,y3)-f(x,y,x2,y2,x3,y3)-f(x1,y1,x,y,x3,y3)-f(x1,y1,x2,y2,x,y)) < 1e-6) cout << "Orz" << endl; else cout << "stO" << endl; } return 0; }
*1128.待补。
1129.记录交换后的映射。
#include<bits/stdc++.h> using namespace std; int a[1005][1005],x[1005],y[1005],n,m,k; int main() { while(~scanf("%d%d%d",&n,&m,&k)) { for(int i = 1;i <= n;i++) x[i] = i; for(int i = 1;i <= m;i++) y[i] = i; for(int i = 1;i <= n;i++) { for(int j = 1;j <= m;j++) scanf("%d",&a[i][j]); } int o,xx,yy; while(k--) { scanf("%d%d%d",&o,&xx,&yy); if(o == 0) swap(x[xx],x[yy]); else swap(y[xx],y[yy]); } for(int i = 1;i <= n;i++) { printf("%d",a[x[i]][y[1]]); for(int j = 2;j <= m;j++) printf(" %d",a[x[i]][y[j]]); printf("\n"); } } return 0; }
1130.C(n,0)+C(n,1)+...+C(n,n) =2^n,0*C(n,0)+1*C(n,1)+2*C(n,2)+...n*C(n,n) = n*2^(n-1)。
#include<bits/stdc++.h> #define LL long long #define MOD 542 using namespace std; int p,d,n; LL qmod(LL a, LL b, LL c) { LL ans = 1; a = a%c; while(b) { if(b&1) ans = ans*a%c; b >>= 1; a = a*a%c; } return ans; } int main() { int T; scanf("%d",&T); while(T--) { scanf("%d%d%d",&p,&d,&n); LL ans = qmod(2,n,MOD)*p%MOD; ans = (qmod(2,n-1,MOD)*d*n+ans)%MOD; printf("%lld\n",ans); } return 0; }
1131.dp[i][j]表示i,j两个下面为首的最序列的个数,从后往前更新,用map记录是否出现过某个值。
#include<bits/stdc++.h> using namespace std; int n,dp[1005][1005]; long long a[1005]; int main() { //freopen("1.txt","r",stdin); while(~scanf("%d",&n)) { memset(dp,0,sizeof(dp)); for(int i = 1;i <= n;i++) scanf("%lld",&a[i]); map<long long,int> mp; long long ans1 = 2e18,ans2 = 2e18,maxx = 2; for(int j = n;j >= 1;j--) { for(int i = j-1;i >= 1;i--) { if(mp.count(a[i]+a[j])) dp[i][j] = max(dp[i][j],dp[j][mp[a[i]+a[j]]]+1); dp[i][j] = max(dp[i][j],2); if(dp[i][j] > maxx || dp[i][j] == maxx && (a[i] < ans1 || a[i] == ans1 && a[j] < ans2)) { maxx = dp[i][j]; ans1 = a[i]; ans2 = a[j]; } } mp[a[j]] = j; } printf("%d\n",maxx); int now1 = mp[ans1],now2 = mp[ans2]; printf("%lld %lld",ans1,ans2); for(int i = 3;i <= maxx;i++) { long long t = a[now1]+a[now2]; now1 = now2; while(a[now2] != t) now2++; printf(" %lld",a[now2]); } printf("\n"); } return 0; }
*1132.待补。
1138.a+b。
#include<bits/stdc++.h> using namespace std; char s; int a,b,c,d; int main() { ios::sync_with_stdio(0); while(cin >> a >> s >> b >> s >> c >> s >> d >> s) cout << a+c << "+" << b+d << "i" << endl; return 0; }
1139.打表二分,注意前面几个特例。
#include<bits/stdc++.h> using namespace std; long long n,f[100],sum[100]; int main() { ios::sync_with_stdio(0); f[0] = 0; f[1] = 1; sum[1] = 1; for(int i = 2;i <= 100;i++) { f[i] = f[i-1]+f[i-2]; sum[i] = sum[i-1]+f[i]; } while(cin >> n) { if(n == 1 || n == 2 || n == 3) cout << "1 1" << endl; else { int x = lower_bound(sum,sum+100,n)-sum; long long y = n-sum[x-1]; if(y > f[x-1]) cout << x << " " << y << endl; else cout << x-1 << " " << f[x-1] << endl; } } return 0; }
1140.kmp,c中的strstr比kmp快10来倍。
#include<bits/stdc++.h> using namespace std; int n; int main() { while(~scanf("%d",&n)) { getchar(); int s = 0; char a[50000],b[50000] = " "; while(n--) { gets(a); strcat(b,a); char *p = b,*o; while(o = strstr(p,"wanshen")) { p = o+7; s++; } strcpy(b,p); } printf("%d\n",s); } return 0; }
1141.取余后模拟。
#include<bits/stdc++.h> using namespace std; long long x,y,a; int main() { while(cin >> x >> y >> a) { a %= x+y; if(a == 0) { cout << "light" << endl; continue; } while(a) { a -= x; if(a <= 0) { cout << "wanshen" << endl; break; } a -= y; if(a <= 0) { cout << "light" << endl; break; } } } return 0; }
1142.记录字符串中出现的字符,然后删除。
#include<bits/stdc++.h> using namespace std; char a[100005],b[100005]; int s[128]; int main() { while(cin >> a >> b) { memset(s,0,sizeof(s)); int flag=0,lena = strlen(a),lenb = strlen(b); for(int i = 0;i < lenb;i++) s[b[i]] = 1; for(int i = 0;i < lena;i++) { if(!s[a[i]]) { putchar(a[i]); flag = 1; } } if(!flag) cout << "EMPTY"; cout << endl; } return 0; }
1143.暴力dfs,注意过程中还原。
#include<bits/stdc++.h> using namespace std; int a[10],vis[10],num[10],ans; bool ok(int x,int z) { if(x == 1) return 1; if(x > 3 && __gcd(z,num[x-3]) != 1) return 0; if(x%3 != 1 && __gcd(z,num[x-1]) != 1) return 0; return 1; } void dfs(int x) { if(x == 9) { ans++; return; } for(int i = 1;i <= 9;i++) { if(vis[i]) continue; if(ok(x+1,a[i])) { vis[i] = 1; num[x+1] = a[i]; dfs(x+1); vis[i] = 0; } } } int main() { while(cin >> a[1]) { for(int i = 2;i <= 9;i++) cin >> a[i]; ans = 0; dfs(0); cout << ans << endl; } return 0; }
1144.合并小的,不一定每一次都是合并k个,第一次先合并不足k的次数,后面都合并k个。
#include<bits/stdc++.h> using namespace std; priority_queue< long long,vector<long long>,greater<long long> > q; int n,k; int main() { ios::sync_with_stdio(0); while(cin >> n >> k) { while(!q.empty()) q.pop(); long long x,ans = 0; for(int i = 1;i <= n;i++) { cin >> x; q.push(x); } while((n-1)%(k-1)) { q.push(0); n++; } while(q.size() != 1) { long long t = 0,sum = 0; while(t++ < k) { sum += q.top(); q.pop(); } ans += sum; q.push(sum); } cout << ans << endl; } return 0; }
1145.矩阵快速幂。
#include<bits/stdc++.h> #define MOD 1000000007 using namespace std; long long l,r,anss[5] = {1,2,3,6,11}; struct matrix { long long m[4][4]; }; matrix ans = { 1,0,0,0, 0,1,0,0, 0,0,1,0, 0,0,0,1,}; matrix base = { 1,1,1,0, 1,0,0,0, 0,1,0,0, 1,0,0,1,}; matrix mul(matrix a, matrix b) { matrix tmp; for(int i = 0; i < 4;i++) { for(int j = 0; j < 4;j++) { tmp.m[i][j] = 0; for(int k = 0; k < 4;k++) tmp.m[i][j] = (tmp.m[i][j]+a.m[i][k]*b.m[k][j])%MOD; } } return tmp; } long long fast_mod(long long n) { matrix x = ans,y = base; while(n) { if(n & 1) { x = mul(x,y); } y = mul(y,y); n >>= 1; } return (x.m[3][0]+x.m[3][1]+x.m[3][2]+2*x.m[3][3])%MOD; } int main() { ios::sync_with_stdio(0); while(cin >> l >> r) { long long x,y; if(l == 0) x = 0; else x = l < 6?anss[l-1]:fast_mod(l-2); y = r < 5?anss[r]:fast_mod(r-1); cout << (y-x+MOD)%MOD << endl; } return 0; }
1146.01背包的变形,达成每种V所需的最小体力。
#include<bits/stdc++.h> using namespace std; int dp[50005],v[1005],w[1005],n,W; int main() { ios::sync_with_stdio(0); while(cin >> n >> W) { memset(dp, 0x3f, sizeof(dp)); dp[0] = 0; int sum = 0; for(int i = 1;i <= n;i++) { cin >> w[i] >> v[i]; sum += v[i]; } for(int i = 1;i <= n;i++) { for(int j = sum;j >= v[i];j--) dp[j] = min(dp[j-v[i]]+w[i],dp[j]); } for(int i = sum;i >= 0;i--) { if(dp[i] <= W) { cout << i << endl; break; } } } return 0; }
1147.先判断和在不在最大和最小的区间内。若在,从后往前贪心。
#include<bits/stdc++.h> using namespace std; int n,l[100005],r[100005],ans[100005],s; int main() { while(~scanf("%d%d",&n,&s)) { int sum1 = 0,sum2 = 0; for(int i = 1;i <= n;i++) { scanf("%d%d",&l[i],&r[i]); sum1 += l[i]; sum2 += r[i]; } if(s < sum1 || s > sum2) { printf("Xue Beng\n"); continue; } int x = s-sum1; for(int i = n;i >= 1;i--) { ans[i] = x >= r[i]-l[i]?r[i]:l[i]+x; x -= ans[i]-l[i]; } printf("%d",ans[1]); for(int i = 2;i <= n;i++) printf(" %d",ans[i]); printf("\n"); } return 0; }
1148.b ≥ phi[c]时,a^b%c = a^(b%phi[c]+phi[c])%c,否则直接算。
#include<bits/stdc++.h> #define LL long long using namespace std; LL a,b,c,y; LL gcd(LL a,LL b) { return b?gcd(b,a%b):a; } LL PowerMod(LL a, LL b, LL c) { LL ans = 1; a = a % c; while(b) { if(b&1) ans = (ans*a)%c; b = b>>1; a = (a*a)%c; } return ans; } LL euler(LL n) { LL res = n,a = n; for(LL i = 2;i*i <= a;i++) { if(a%i == 0) { res = res/i*(i-1); while(a%i == 0) a /= i; } } if(a > 1) res = res/a*(a-1); return res; } int main() { while(~scanf("%lld%lld%lld%lld",&a,&b,&c,&y)) { LL t = euler(y); if(log(b) < 9/c) { printf("%lld\n",PowerMod(a,PowerMod(b,c,1e9+7),y)); } else printf("%lld\n",PowerMod(a,PowerMod(b,c,t)+t,y)); } return 0; }
1149.打表预处理,容斥。
#include<bits/stdc++.h> #define MOD 1000000007 #define LL long long using namespace std; LL fac[2000005],inv[2000005],n,m,k; LL PowerMod(LL a, LL b, LL c) { LL ans = 1; a = a % c; while(b) { if(b&1) ans = (ans*a)%c; b = b>>1; a = (a*a)%c; } return ans; } inline LL c(LL n,LL m) { if(m > n) return 0; return fac[n]*inv[m]%MOD*inv[n-m]%MOD; } int main() { ios::sync_with_stdio(0); fac[0] = 1; for(int i = 1;i <= 2000000;i++) fac[i] = fac[i-1]*i%MOD; inv[2000000] = PowerMod(fac[2000000],MOD-2,MOD); for(int i = 1999999;i >= 0;i--) inv[i] = inv[i+1]*(i+1)%MOD; while(cin >> n >> m >> k) { LL ans = c(n+m-1,m),x = -1; for(int i = 1;i <= n;i++,x = -x) { LL t = m-i*(k+1); if(t < 0) break; ans = (ans+x*(c(n,i)*c(n+t-1,t)%MOD)+MOD)%MOD; } cout << ans << endl; } return 0; }
1150.减法。
#include<bits/stdc++.h> using namespace std; int a; int main() { while(cin >> a) cout << a-10 << endl; return 0; }
1151.分情况讨论。
#include<bits/stdc++.h> using namespace std; long long a,b,c; int main() { while(cin >> a >> b >> c) { if(a==0&&b==0&&c==0) { cout << "inf" << endl; continue; } if(a==0&&b!=0) { cout << 1 << endl; continue; } if(a==0&&b==0&&c!=0) { cout << 0 << endl; continue; } long long x=b*b-4*a*c; if(x==0) cout << 1 << endl; else if(x>0) cout << 2 << endl; else cout << 0 << endl; } return 0; }
1152.map记录。
#include<bits/stdc++.h> using namespace std; struct st { string name,course; }; map<int,st> mp; map<int,st>::iterator it; int main() { int n,m; while(cin >> n >> m) { mp.clear(); string a,c,d; int b; cin >> a >> c; for(int i = 1;i <= n;i++) { cin >> a >> b; mp[b].name = a; mp[b].course = "NULL"; } cin >> a >> c >> d; for(int i = 1;i <= m;i++) { cin >> a >> b >> c; mp[b].course = c; } cout << "Name StuNum CourseName" << endl; for(it = mp.begin();it != mp.end();it++) cout << it->second.name << ' ' << it->first << ' ' << it->second.course << endl; } return 0; }
1153.比较斜率排序。
#include<bits/stdc++.h> #define LL long long using namespace std; struct line { LL x,y; }a[100005]; int n; bool cmp(line X,line Y) { return X.y*Y.x < X.x*Y.y; } int main() { while(~scanf("%d",&n)) { int cnt = 0; LL x,y,xx,yy,temp = 0; for(int i = 1;i <= n;i++) { scanf("%lld%lld%lld%lld",&x,&y,&xx,&yy); if(x == xx) temp++; else if(x < xx) { a[cnt].x = xx-x; a[cnt].y = yy-y; cnt++; } else { a[cnt].x = x-xx; a[cnt].y = y-yy; cnt++; } } sort(a,a+cnt,cmp); LL ans = temp*(temp-1)/2; LL num = 1; for(int i = 1;i < cnt;i++) { if(a[i].x*a[i-1].y == a[i].y*a[i-1].x) num++; else { ans += num*(num-1)/2; num = 1; } } ans += num*(num-1)/2; printf("%lld\n",ans); } return 0; }
1154.统计连续0串的个数。
#include<bits/stdc++.h> using namespace std; string s; int main() { ios::sync_with_stdio(0); while(cin >> s) { int len = s.length(); int ans = 0,flag = 0; for(int now = 0;now < len;now++) { if(flag) { while(now < len) { if(s[now] == '1') { ans++; flag = 0; break; } else now++; } } else if(s[now] == '0') flag = 1; } if(flag) ans++; cout << ans << endl; } return 0; }
1155.先确定在往里数的第几个圈上,然后根据位置确定数字。
#include<bits/stdc++.h> using namespace std; long long k,x,y,ans; int main() { ios::sync_with_stdio(0); while(cin >> k >> x >> y) { long long p = min(x,y); p = min(p,k-x+1); p = min(p,k-y+1); long long dis = x-p+y-p; if(x <= y) ans = 4*(p-1)*(k-p+1)+1+dis; else ans = 4*p*(k-p)+1-dis; cout << ans << endl; } return 0; }
1156.递减的单调队列,保存人的编号和入队耐心-入队时间。
#include<bits/stdc++.h> using namespace std; struct st { int num,t; }s; deque<st> q; int n,x; int main() { while(~scanf("%d",&n)) { while(!q.empty()) q.pop_back(); int out = 1,cnt = 1; for(int i = 1;i <= n;i++) { scanf("%d",&x); switch(x) { case 1: int tt; scanf("%d",&tt); s.t = tt-i; s.num = cnt++; while(!q.empty() && q.back().t <= s.t) q.pop_back(); q.push_back(s); break; case 2: if(q.front().num == out++) q.pop_front(); break; case 3: printf("%d\n",q.front().t+i); } } } return 0; }
1157.一条一条加边,求max和从小边往大边加,求min和从大边往小边加,用并查集计点数。
#include<bits/stdc++.h> using namespace std; int n,pre[100005],point[100005]; struct line { int v,u,w; friend bool operator<(line x,line y) { return x.w < y.w; } }l[100005]; int findd(int x) { return x == pre[x]?x:pre[x] = findd(pre[x]); } int main() { while(~scanf("%d",&n)) { for(int i = 1;i < n;i++) scanf("%d%d%d",&l[i].u,&l[i].v,&l[i].w); sort(l+1,l+n); long long ans = 0; for(int i = 1;i <= n;i++) { pre[i] = i; point[i] = 1; } for(int i = 1;i < n;i++) { int x = findd(l[i].u),y = findd(l[i].v); ans += (long long)point[x]*point[y]*l[i].w; pre[x] = y; point[y] += point[x]; } for(int i = 1;i <= n;i++) { pre[i] = i; point[i] = 1; } for(int i = n-1;i >= 1;i--) { int x = findd(l[i].u),y = findd(l[i].v); ans -= (long long)point[x]*point[y]*l[i].w; pre[x] = y; point[y] += point[x]; } printf("%lld\n",ans); } return 0; }
1158.规律C(x+k,x+y),打表预处理。
#include<bits/stdc++.h> #define LL long long #define MOD (long long)(1e9+7) using namespace std; int x,y,k; LL fac[2000005]; LL PowerMod(LL a, LL b, LL c) { LL ans = 1; a = a % c; while(b) { if(b&1) ans = (ans*a)%c; b = b>>1; a = (a*a)%c; } return ans; } LL inv(LL x) { return PowerMod(x,MOD-2,MOD); } int main() { fac[1] = 1; for(int i = 2;i <= 2000000;i++) fac[i] = fac[i-1]*i%MOD; while(~scanf("%d%d%d",&x,&y,&k)) { if(y == k) printf("1\n"); else if(y < k) printf("0\n"); else printf("%lld\n",fac[x+y]*inv(fac[x+k])%MOD*inv(fac[y-k])%MOD); } return 0; }
1159.floyd动态更新,首要要考虑重边和环,然后开放一个点就要更新相关最短路,而且更新的顺序有要求。
#include<bits/stdc++.h> #define INF 0x3f3f3f3f using namespace std; int n,m,t,a[305][305],ok[305]; int main() { while(~scanf("%d%d%d",&n,&m,&t)) { memset(a,0x3f,sizeof(a)); memset(ok,0,sizeof(ok)); for(int i = 0;i < n;i++) a[i][i] = 0; while(m--) { int u,v,w; scanf("%d%d%d",&u,&v,&w); if(u == v) continue; a[u][v] = min(a[u][v],w); } while(t--) { int o; scanf("%d",&o); if(o == 0) { int x; scanf("%d",&x); if(ok[x]) printf("lab %d has been repaired!\n",x); else { ok[x] = 1; for(int i = 0;i < n;i++) { for(int j = 0;j < n;j++) { if(!ok[i] || !ok[j]) continue; a[j][x] = min(a[j][x],a[j][i]+a[i][x]); } } for(int i = 0;i < n;i++) { for(int j = 0;j < n;j++) { if(!ok[i] || !ok[j]) continue; a[x][j] = min(a[x][j],a[x][i]+a[i][j]); } } for(int i = 0;i < n;i++) { for(int j = 0;j < n;j++) { if(!ok[i] || !ok[j]) continue; a[i][j] = min(a[i][j],a[i][x]+a[x][j]); } } } } else { int u,v; scanf("%d%d",&u,&v); if(!ok[u] || !ok[v]) printf("help %d %d\n",u,v); else if(a[u][v] == INF) printf("no path\n"); else printf("%d\n",a[u][v]); } } } return 0; }
1160.set模拟,貌似代码有点问题,直接过了,好像是询问都是按时间顺序来的。
#include<bits/stdc++.h> using namespace std; int n,m; struct ss { int num,t,o; }a[1000005]; set<int> s; bool cmp(ss x,ss y) { return x.t < y.t; } int main() { scanf("%d%d",&n,&m); for(int i = 1;i <= n;i++) scanf("%d%d%d",&a[i].o,&a[i].t,&a[i].num); sort(a+1,a+1+n,cmp); int cnt = 1; for(int i = 1;i <= m;i++) { int p,q; scanf("%d%d",&p,&q); while(cnt <= n&& a[cnt].t < p) { if(a[cnt].o == 1) s.insert(a[cnt].num); else s.erase(a[cnt].num); cnt++; } if(s.count(q)) printf("YES\n"); else printf("NO\n"); } return 0; }
1161.规律,列方程推一下,其中某一个村庄假设不动,动其他n-1个,最后转化成求绝对值最小问题。
#include<bits/stdc++.h> #define LL long long using namespace std; LL a[1000005] = {0}; int n; int main() { while(~scanf("%d",&n) && n > 0) { LL sum1 = 0,sum2 = 0; for(int i = 1;i <= n;i++) { scanf("%lld",&a[i]); sum1 += a[i]; } for(int i = 1;i <= n;i++) { LL t; scanf("%lld",&t); sum2 += t; a[i] = a[i-1]+t-a[i]; } if(sum1 != sum2) { printf("No way\n"); continue; } sort(a,a+n); LL t = a[n/2],ans = 0; for(int i = 0;i < n;i++) ans += abs(t-a[i]); printf("%lld\n",ans); } return 0; }
1162.二分补课次数,树形dp判断。
#include<bits/stdc++.h> using namespace std; int n,m,k,ok,a[1000005],b[1000005],minn[1000005],cnt[1000005]; bool vis[1000005]; vector<int> v[1000005]; void dfs(int now) { minn[now] = a[now]; for(int i = 0;i < v[now].size();i++) { int t = v[now][i]; if(!vis[t]) { vis[t] = 1; dfs(t); } minn[now] = min(minn[now],minn[t]); } minn[now] += k*cnt[now]; } bool pan(int x) { memset(cnt,0,sizeof(cnt)); memset(vis,0,sizeof(vis)); memset(minn,0,sizeof(minn)); for(int i = 1;i <= x;i++) cnt[b[i]]++; ok = 0; for(int i = 1;i <= n;i++) { if(vis[i]) continue; dfs(i); if(minn[i] < 60) return 0; } ok = 1; return 1; } int main() { ios::sync_with_stdio(0); scanf("%d%d%d",&n,&m,&k); for(int i = 1;i < n;i++) { int x,y; scanf("%d%d",&x,&y); v[x].push_back(y); } for(int i = 1;i <= n;i++) scanf("%d",&a[i]); for(int i = 1;i <= m;i++) scanf("%d",&b[i]); int l = 0,r = m; while(l < r) { int mid = (l+r)/2; if(pan(mid)) r = mid; else l = mid+1; } pan(l); if(ok) printf("%d\n",l); else printf("mdzz\n"); return 0; }
1163.扫一边,动态维护每个质因数对应的最大最小值,树状数组位数累和。
#include<bits/stdc++.h> using namespace std; int n,a[10005],c[10005],minn[100005],maxx[100005] = {0}; long long tree[100005] = {0},ans[10005]; inline int lowbit(int x) { return x&-x; } void add(int pos,int x) { while(pos <= 100000) { tree[pos] += x; pos += lowbit(pos); } } long long getsum(int pos) { long long sum = 0; while(pos > 0) { sum += tree[pos]; pos -= lowbit(pos); } return sum; } int main() { while(~scanf("%d",&n) && n) { for(int i = 1;i <= n;i++) scanf("%d",&a[i]); for(int i = 1;i <= n;i++) scanf("%d",&c[i]); memset(maxx,0,sizeof(maxx)); memset(minn,0x3f,sizeof(minn)); memset(tree,0,sizeof(tree)); for(int i = 1;i <= n;i++) { int x = a[i]; int mi = 0x3f3f3f3f,ma = 0; for(int j = 2;j*j <= x;j++) { if(x%j == 0) { while(x%j == 0) x /= j; mi = min(mi,minn[j]); ma = max(ma,maxx[j]); minn[j] = min(minn[j],a[i]); maxx[j] = max(maxx[j],a[i]); } } if(x > 1) { mi = min(mi,minn[x]); ma = max(ma,maxx[x]); minn[x] = min(minn[x],a[i]); maxx[x] = max(maxx[x],a[i]); } if(mi == 0x3f3f3f3f) mi = 0; ans[i] = getsum(ma)-getsum(mi-1); add(a[i],c[i]); } printf("%lld",ans[1]); for(int i = 2;i <= n;i++) printf(" %lld",ans[i]); printf("\n"); } return 0; }
1164.因为存孩子会爆,只能用孩子存父节点,然后逆向的dfs,期间需要一个数组保存累加值。
#include<bits/stdc++.h> using namespace std; int a[10000005],pre[10000005] = {0},sum[10000005] = {0},n,u,v; bool vis[10000005] = {0}; long long dfs(int pos) { if(vis[pos]) return 0; vis[pos] = 1; if(!pre[pos]) { sum[pos] -= a[pos]; return abs(sum[pos]); } long long t = dfs(pre[pos]); a[pos] += sum[pre[pos]]; t += abs(a[pos]); sum[pos] += sum[pre[pos]]-a[pos]; return t; } int main() { scanf("%d",&n); for(int i = 1;i < n;i++) { scanf("%d%d",&u,&v); pre[v] = u; } for(int i = 1;i <= n;i++) scanf("%d",&a[i]); long long ans = 0; for(int i = 1;i <= n;i++) ans += dfs(i); printf("%lld\n",ans); return 0; }
1165.题目https://pan.baidu.com/s/1Ro3vR-L_7mnDfbIKjRj2sg
旋转坐标,求二维前缀和。
#include<bits/stdc++.h> using namespace std; int n,m,k,a[2005][2005],b[2005][2005],mp[805][805],sum[805][805],cnt[805][805]; int main() { while(~scanf("%d%d%d",&m,&n,&k)) { memset(a,0,sizeof(a)); memset(b,0,sizeof(b)); int maxx = max(n,m),nn = 2*maxx; for(int i = 1;i <= n;i++) { for(int j = 1;j <= m;j++) { int ii = i-j+maxx,jj = i+j; scanf("%d",&a[ii][jj]); b[ii][jj] = 1; mp[i][j] = a[ii][jj]; } } for(int i = 1;i <= nn;i++) { for(int j = 1;j <= nn;j++) { a[i][j] += a[i][j-1]+a[i-1][j]-a[i-1][j-1]; b[i][j] += b[i][j-1]+b[i-1][j]-b[i-1][j-1]; } } for(int i = 1;i <= n;i++) { for(int j = 1;j <= m;j++) { int ii = i-j+maxx,jj = i+j; int x1 = max(1,ii-k),y1 = max(1,jj-k); int x2 = min(nn,ii+k),y2 = min(nn,jj+k); sum[i][j] = a[x2][y2]-a[x1-1][y2]-a[x2][y1-1]+a[x1-1][y1-1]; cnt[i][j] = b[x2][y2]-b[x1-1][y2]-b[x2][y1-1]+b[x1-1][y1-1]; } } for(int i = 1;i <= n;i++) { printf("%.0f",1.0*(sum[i][1]-mp[i][1])/(cnt[i][1]-1)+1e-8); for(int j = 2;j <= m;j++) printf(" %.0f",1.0*(sum[i][j]-mp[i][j])/(cnt[i][j]-1)+1e-8); printf("\n"); } } return 0; }
1166.题目https://pan.baidu.com/s/1Ro3vR-L_7mnDfbIKjRj2sg
将一个串扩充至两倍,另一个串变化几种形态在里面找是否存在相同字串,strstr方便又快速。
#include<bits/stdc++.h> using namespace std; char a[200005],b[100005]; int n; void change() { for(int i = 0;i < n;i++) { if(b[i] == '3') b[i] = '0'; else b[i] += 1; } } int main() { while(~scanf("%d",&n)) { getchar(); gets(a); gets(b); for(int i = 0;i < n;i++) a[i+n] = a[i]; a[2*n] = 0; char *p = NULL; for(int i = 0;i < 4;i++) { p = strstr(a,b); if(p) break; if(i != 3) change(); } if(p) printf("yes\n"); else printf("no\n"); } return 0; }
*1167.待补。
1168.都取出现次数最少的那个字母就可以了。
#include<bits/stdc++.h> using namespace std; char a[100005]; int x[30],y[30]; int main() { int T; scanf("%d",&T); for(int c = 1;c <= T;c++) { memset(x,0,sizeof(x)); memset(y,0,sizeof(y)); scanf("%s",a); int len = strlen(a); for(int i = 0;i < len;i++) { if('a' <= a[i] && a[i] <= 'z') x[a[i]-'a']++; else y[a[i]-'A']++; } sort(x,x+26); sort(y,y+26); printf("Case %d: %d\n",c,min(x[0],y[0])); } return 0; }
1169.不断除以2,直到奇数,操作次数的奇偶性。
#include<bits/stdc++.h> using namespace std; int f(long long x) { if(x&1) return 0; else return f(x/2)^1; } int main() { int T; scanf("%d",&T); while(T--) { long long x; scanf("%d",&x); if(f(x) == 0) printf("First Box\n"); else printf("Second Box\n"); } }
1170.优化一下暴力的过程,将数量一样的放一起算。
#include<bits/stdc++.h> #define LL long long using namespace std; LL n,m; LL gcd(LL x,LL y) { return y?gcd(y,x%y):x; } LL c(LL x,LL y) { return (y*(y+1)*(2*y+1))/6-((x-1)*x*(2*x-1))/6; } int main() { while(~scanf("%lld%lld",&n,&m) && n && m) { LL ans = 0; int now = 1; while(now <= n) { int t = n/now,endd = min(m,n/t); ans += t*c(now,endd); if(endd == m) break; now = endd +1; } LL x = n*m; LL g = gcd(ans,x); printf("%lld/%lld\n",ans/g,x/g); } }
1171.dp[i][j][k]表示前i行里有j列1个,k列两个的方案数,自底向上dp可以省略一维空间,记忆化应该快一点。
#include<bits/stdc++.h> #define MOD 14020130063 using namespace std; int n,m; long long dp[105][105][105]; long long dfs(int x,int y,int z) { if(x < 0 || y < 0 || z < 0 || y+z > m) return 0; if(dp[x][y][z] != -1) return dp[x][y][z]; dp[x][y][z] = (dfs(x-1,y,z)+(m-(y-1)-z)*dfs(x-1,y-1,z)+(y+1)*dfs(x-1,y+1,z-1)+(m-(y-2)-z)*(m-(y-2)-z-1)/2*dfs(x-1,y-2,z)+(y+2)*(y+2-1)/2*dfs(x-1,y+2,z-2)+y*(m-y-(z-1))*dfs(x-1,y,z-1))%MOD; return dp[x][y][z]; } int main() { ios::sync_with_stdio(0); while(cin >> n >> m) { if(m > n) swap(n,m); memset(dp,-1,sizeof(dp)); dp[1][0][0] = 1; dp[1][1][0] = m; dp[1][2][0] = m*(m-1)/2; long long ans = 0; for(int i = 0;i <= m;i++) { for(int j = 0;i+j <= m;j++) ans = (ans+dfs(n,i,j))%MOD; } cout << ans << endl; } return 0; }
1172.容量为sum/2的01背包。
#include<bits/stdc++.h> using namespace std; int n,w[205],dp[200005]; int main() { ios::sync_with_stdio(0); while(cin >> n) { memset(dp,0,sizeof(dp)); int sum = 0; for(int i = 1;i <= n;i++) { cin >> w[i]; sum += w[i]; } int endd = sum/2; for(int i = 1;i <= n;i++) { for(int j = endd;j >= w[i];j--) { dp[j] = max(dp[j],dp[j-w[i]]+w[i]); } } cout << sum-dp[endd]*2 << endl; } return 0; }
1173.是否为3的倍数。
#include<bits/stdc++.h> using namespace std; int n; int main() { ios::sync_with_stdio(0); while(cin >> n) { if(n%3) cout << "Yes" << endl; else cout << "No" << endl; } return 0; }
*1174.待补。
1175.拿k长度的线段扫一遍,map维护数量。
#include<bits/stdc++.h> using namespace std; int n,k,a[200005] = {0}; int main() { while(~scanf("%d%d",&n,&k)) { for(int i = 1;i <= n;i++) scanf("%d",&a[i]); map<int,int> mp; for(int i = 1;i < k;i++) mp[a[i]]++; int ans = 0; for(int i = k;i <= n;i++) { mp[a[i]]++; if(mp.size() == k) ans++; if(--mp[a[i-k+1]] == 0) mp.erase(a[i-k+1]); } printf("%d\n",ans); } return 0; }
1176.渡河dp,每次分两批送走最大的两个人。
#include<bits/stdc++.h> using namespace std; int a[100005],n; int main() { while(cin >> n) { for(int i = 1;i <= n;i++) cin >> a[i]; sort(a+1,a+1+n); long long ans = 0; while(n) { if(n == 1) { ans += a[1]; break; } if(n == 2) { ans += a[2]; break; } if(n == 3) { ans += a[1]+a[2]+a[3]; break; } else { ans += min(2*a[1]+a[n]+a[n-1],a[1]+2*a[2]+a[n]); n -= 2; } } cout << ans << endl; } return 0; }
1177.排序后树状数组维护。
#include<bits/stdc++.h> using namespace std; int tree[1000005],n,m,cnt = 1,ans[100005]; struct star { int num,x,y,o; }a[200005]; bool cmp(star X,star Y) { if(X.x == Y.x) return X.y < Y.y; return X.x < Y.x; } inline int lowbit(int x) { return x & (-x); } void update(int pos,int x) { while(pos <= 1000001) { tree[pos] += x; pos += lowbit(pos); } } int getsum(int pos) { int sum = 0; while(pos > 0) { sum += tree[pos]; pos -= lowbit(pos); } return sum; } int main() { while(~scanf("%d%d",&n,&m)) { printf("Case #%d:\n",cnt++); memset(tree,0,sizeof(tree)); for(int i = 1;i <= n;i++) { scanf("%d%d",&a[i].x,&a[i].y); a[i].o = 1; } for(int i = n+1;i <= n+m;i++) { scanf("%d%d",&a[i].x,&a[i].y); a[i].num = i-n; a[i].o = 0; } sort(a+1,a+1+n+m,cmp); for(int i = 1;i <= n+m;i++) { if(a[i].o) update(a[i].y+1,1); else ans[a[i].num] = getsum(a[i].y+1); } for(int i = 1;i <= m;i++) printf("%d\n",ans[i]); } return 0; }
1179.先打表单个硬币能凑成的数的最小硬币个数,枚举每种硬币及个数,更新答案。
#include<bits/stdc++.h> using namespace std; int a[5005],ans[10000005] = {0},n,s,q; int main() { memset(ans,0x3f,sizeof(ans)); cin >> n >> s; for(int i = 1;i <= n;i++) { cin >> a[i]; for(int j = 1;j <= s;j++) ans[a[i]*j] = min(ans[a[i]*j],j); } cin >> q; while(q--) { int t,x = 2e9; cin >> t; for(int i = 1;i <= n;i++) { int endd = min(s,t/a[i]); for(int j = 1;j <= endd;j++) { int left = t-j*a[i]; if(left == 0) x = min(x,j); else if(ans[left] && ans[left]+j <= s) x = min(x,ans[left]+j); } } if(x == 2e9) cout << -1 << endl; else cout << x << endl; } return 0; }
1180.dp[i][j][k]表示取第i个珠子颜色为j且末尾有k个连续的珠子的总数。
k = 1时,dp[i][j][k] = sumx≠j且1≤y≤k(dp[i-1][x][y])
k ≠ 1时,dp[i][j][k] = dp[i-1][j][k-1]
由于对称性,j不影响dp[i][j][k]结果,则忽略第二维,dp[i][1] = sum1≤y≤k(dp[i-1][y])*(m-1)
利用矩阵快速幂,计算sum1≤x≤k-1(dp[n][x]),再乘以m种颜色即为结果。
#include<bits/stdc++.h> #define MOD 23333 using namespace std; long long n,m,k; struct matrix { long long m[105][105]; }; matrix one = {0},base = {0}; matrix mul(matrix a, matrix b) { matrix tmp; for(int i = 0; i < k-1;i++) { for(int j = 0; j < k-1;j++) { tmp.m[i][j] = 0; for(int K = 0;K < k-1;K++) tmp.m[i][j] = (tmp.m[i][j]+a.m[i][K]*b.m[K][j])%MOD; } } return tmp; } long long fast_mod(long long n) { matrix ans = one,y = base; while(n) { if(n&1) ans = mul(ans,y); y = mul(y,y); n /= 2; } long long res = 0; for(int i = 0;i < k-1;i++) res = (res+ans.m[i][0])%MOD; return res*m%MOD; } int main() { ios::sync_with_stdio(false); for(int i = 0;i < 100;i++) one.m[i][i] = 1; for(int i = 1;i < 100;i++) base.m[i][i-1] = 1; while(cin >> n >> m >> k) { for(int i = 0;i < k-1;i++) base.m[0][i] = m-1; cout << fast_mod(n-1) << endl; } return 0; }
1181.因为只有一组数据,直接开vector存每一次的状态,把树状数组改一下就可以了。
#include<bits/stdc++.h> using namespace std; int a[1000005] = {0},n,q,o,t = 0,c = 0; vector< pair<int,int> > v[1000005]; vector< pair<int,int> >::iterator it; inline int lowbit(int x) { return x&(-x); } void update(int pos,int x) { while(pos <= n) { int temp = 0; if(!v[pos].empty()) temp = v[pos].back().second; v[pos].push_back(make_pair(t,temp+x)); pos += lowbit(pos); } } int getsum(int pos,int tt) { int sum = 0; while(pos > 0) { it = upper_bound(v[pos].begin(),v[pos].end(),make_pair(tt,0)); if(it != v[pos].end() && it->first == tt) sum += it->second; else if(it != v[pos].begin()) { it--; sum += it->second; } pos -= lowbit(pos); } return sum; } int main() { ios::sync_with_stdio(false); cin >> n >> q; while(q--) { cin >> o; if(o == 1) { t++; int i,x; cin >> i >> x; c = i^c; update(c,x); a[c] += x; c = a[c]; } else { int l,r,tt; cin >> l >> r >> tt; c = getsum(r^c,tt)-getsum((l^c)-1,tt); cout << c << endl; } } return 0; }
1182.快速乘。
#include<bits/stdc++.h> #define LL long long #define MOD 23333333333 using namespace std; LL n,m; LL qmul(LL a, LL b, LL c) { LL ans = 0; a = a%c; while(b) { if(b&1) ans = (ans+a)%c; b >>= 1; a = (a+a)%c; } return ans; } int main() { while(cin >> n >> m) { LL x = m/3,y = m%3,ans = 0; if(x%2) ans = qmul(x*3,(2*n+x+1)/2,MOD); else ans = qmul(x*3/2,2*n+x+1,MOD); for(int i = 0;i < y;i++) ans = (ans+n+x+i)%MOD; cout << ans << endl; } return 0; }
1183.划分问题,dp[i][j] = dp[i-1][j-1]+dp[i-j][j]。
#include<bits/stdc++.h> #define MOD 1000000007 using namespace std; long long dp[1005][1005] = {0}; int n,m; int main() { for(int i = 1;i <= 1000;i++) dp[i][1] = 1; for(int i = 2;i <= 1000;i++) { for(int j = 2;j <= i;j++) dp[i][j] = (dp[i-1][j-1]+dp[i-j][j])%MOD; } for(int i = 1;i <= 1000;i++) { for(int j = 1;j <= 1000;j++) dp[i][j] = (dp[i][j-1]+dp[i][j])%MOD; } while(scanf("%d%d",&n,&m) && n && m) printf("%lld\n",dp[n][m]); return 0; }
1184.Sprague-Grundy定理。
#include<bits/stdc++.h> using namespace std; int n; int main() { while(~scanf("%d",&n)) { int ans = 0,t; for(int i = 1;i <= n;i++) { scanf("%d",&t); ans ^= t%3; } if(ans) printf("Yes\n"); else printf("No\n"); } return 0; }
1185.二分时间。
#include<bits/stdc++.h> using namespace std; int m,k,t[100005]; bool ok(int x) { int cnt = 0,sum = 0; for(int i = 1;i <= m;i++) { if(sum+t[i] < x) sum += t[i]; else if(sum+t[i] == x) { cnt++; sum = 0; } else { cnt++; sum = t[i]; } } if(sum) cnt++; if(cnt > k) return 1; return 0; } int main() { ios::sync_with_stdio(false); while(cin >> m >> k) { for(int i = 1;i <= m;i++) cin >> t[i]; int l = 1,r = 100000000; while(l < r) { int mid = (l+r)/2; if(ok(mid)) l = mid+1; else r = mid; } cout << l << endl; } return 0; }
1186.dfs。
#include<bits/stdc++.h> using namespace std; int n = 0,m,len[55],vis[55][55] = {0},sum,ok; int dx[4] = {-1,0,1,0}; int dy[4] = {0,-1,0,1}; string a[55]; void dfs(int x,int y) { vis[x][y] = 1; sum++; for(int i = 0;i < 4;i++) { int xx = x+dx[i],yy = y+dy[i]; if(xx < 1 || xx > n || yy < 1 || yy > len[x]) { ok = 1; continue; } if(vis[xx][yy]) continue; if(a[xx][yy] == '#') continue; dfs(xx,yy); } } int main() { ios::sync_with_stdio(false); while(cin >> a[++n]) { len[n] = a[n].length(); a[n] = ' '+a[n]; } int ans = 0; for(int i = 1;i <= n;i++) { for(int j = 1;j <= len[i];j++) { if(vis[i][j] || a[i][j] == '#') continue; sum = 0; ok = 0; dfs(i,j); if(!ok) ans += sum; } } cout << ans << endl; return 0; }
1187.每个点按度排序,从度小的点开始,把每个点邻接表中在该点前面的点都删掉。然后对于每一条边,统计公共点的个数和。
#include<bits/stdc++.h> using namespace std; int n,m,vis[100005],x[100005],y[100005]; vector<int> v[100005]; struct xx { int cnt,id; friend bool operator<(xx a,xx b) { return a.cnt < b.cnt; } }a[100005]; int main() { int T; scanf("%d",&T); while(T--) { scanf("%d%d",&n,&m); memset(vis,0,sizeof(vis)); for(int i = 1;i <= n;i++) v[i].clear(); for(int i = 1;i <= n;i++) a[i].id = i,a[i].cnt = 0; for(int i = 1;i <= m;i++) { scanf("%d%d",&x[i],&y[i]); v[x[i]].push_back(y[i]); v[y[i]].push_back(x[i]); a[x[i]].cnt++; a[y[i]].cnt++; } sort(a+1,a+1+n); for(int i = 1;i <= n;i++) { int tt = a[i].id; for(int j = 0;j < v[tt].size();j++) { int t = v[tt][j]; if(vis[t]) v[tt].erase(v[tt].begin()+j),j--; } sort(v[tt].begin(),v[tt].end()); vis[tt] = 1; } long long ans = 0; for(int i = 1;i <= m;i++) { int t = x[i],tt = y[i]; int now1 = 0,now2 = 0; while(now1 < v[t].size() && now2 < v[tt].size()) { if(v[t][now1] < v[tt][now2]) now1++; else if(v[t][now1] > v[tt][now2]) now2++; else { ans++; now1++; now2++; } } } printf("%lld\n",ans); } return 0; }
1188.递推,找公式。
#include<bits/stdc++.h> using namespace std; long long n; int main() { ios::sync_with_stdio(false); while(cin >> n) cout << 1+n*(n+1)/2 << endl; return 0; }
1189.输出注意空格。
#include<bits/stdc++.h> using namespace std; int n; int main() { ios::sync_with_stdio(false); while(cin >> n) { for(int i = 1;i <= n;i++) { int t = 26-i; while(t--) cout << " "; for(int j = 0;j < i;j++) cout << (char)('A'+j); for(int j = i-2;j >= 0;j--) cout << (char)('A'+j); cout << endl; } } return 0; }
1190.连续平方数求和,公式,逆元。
#include<bits/stdc++.h> #define LL long long using namespace std; long long n,p; LL qmod(LL a, LL b, LL c) { LL ans = 1; a = a%c; while(b) { if(b&1) ans = ans*a%c; b >>= 1; a = a*a%c; } return ans; } LL inv(LL a,LL b) { return qmod(a,b-2,b); } int main() { ios::sync_with_stdio(false); while(cin >> n >> p) { cout << n%p*(n+1)%p*(2*n+1)%p*inv(6,p)%p << endl; } return 0; }
1191.给每一类记录一个标准。
#include<bits/stdc++.h> #define LL long long using namespace std; long long n; vector<string> v[5005]; int main() { ios::sync_with_stdio(false); while(cin >> n) { int cnt= 0; for(int i = 1;i <= n;i++) v[i].clear(); for(int i = 1;i <= n;i++) { string s; cin >> s; string ss = s; sort(ss.begin(),ss.end()); int p = 1,flag = 0; for(;p <= cnt;p++) { if(v[p][0] == ss) { v[p].push_back(s); flag = 1; break; } } if(!flag) { v[++cnt].push_back(ss); v[cnt].push_back(s); } } for(int i = 1;i <= cnt;i++) { cout << v[i][1]; for(int j = 2;j <v[i].size();j++) cout << " " << v[i][j]; cout << endl; } } return 0; }
1192.线段扫一遍比较每一段。
#include<bits/stdc++.h> #define LL long long using namespace std; int n,k,a[200005]; int main() { ios::sync_with_stdio(false); while(cin >> n >> k) { long long ans = 0,now = 0; for(int i = 1;i <= n;i++) cin >> a[i]; for(int i = 1;i <= k;i++) now += a[i]; ans = now; for(int i = k+1;i <= n;i++) { now = now+a[i]-a[i-k]; ans = min(now,ans); } cout << ans << endl; } return 0; }
1193.Sprague-Grundy定理。
#include<bits/stdc++.h> #define LL long long using namespace std; int a,b,c,d; int main() { ios::sync_with_stdio(false); while(cin >> a >> b >> c >> d) { int t = a%(c+1),tt = b%(d+1); if(t^tt) cout << "NUO!" << endl; else cout << "NO!" << endl; } return 0; }
1194.求解模方程a^x=b(mod n),n为素数。大步小步模版。
#include<bits/stdc++.h> #define LL long long using namespace std; LL pow_mod(LL a,LL b,LL n) { LL s=1; while(b) { if(b&1) s=(s*a)%n; a=(a*a)%n; b=b>>1; } return s; } LL log_mod (LL a,LL b,LL n) { LL m,v,e=1,i; m=ceil(sqrt(n+0.5)); //x=i*m+j //v=inv(pow_mod(a,m,n),n); //a^m*v=1(mod n) v=pow_mod(a,n-m-1,n); map<LL,LL>x; x[1]=m; for(i=1;i<m;i++) { e=(e*a)%n; if(!x[e])x[e]=i; } for(i=0;i<m;i++) { if(x[b]) { LL num=x[b]; x.clear(); return i*m+(num==m?0:num); } b=(b*v)%n; //b=b/(a^m) } return -1; } int main() { LL a,b; while(scanf("%lld%lld",&a,&b)!=EOF) { LL ans1=log_mod(3,a,2147483647),ans2 = log_mod(3,b,2147483647); if(ans1==-1 || ans2 == -1) printf("No Solution\n"); else printf("%lld\n",pow_mod(3,ans1*ans2,2147483647)); } return 0; }
1195.最短路模版。
#include<bits/stdc++.h> using namespace std; int n,m,a[105][105],vis[105],dis[105]; int main() { ios::sync_with_stdio(false); int T; cin >> T; while(T--) { cin >> m; n = 0; memset(a,0x3f,sizeof(a)); while(m--) { int x,y,z; cin >> x >> y >> z; a[x][y] = a[y][x] = min(a[x][y],z); n = max(n,x); n = max(n,y); } int s,d; cin >> s >> d; memset(vis,0,sizeof(vis)); memset(dis,0x3f,sizeof(dis)); dis[s] = 0; for(int i = 1;i <= n;i++) { int k = -1,minn = 0x3f3f3f3f; for(int j = 1;j <= n;j++) { if(vis[j]) continue; if(minn > dis[j]) { minn = dis[j]; k = j; } } if(k == -1) break; vis[k] = 1; for(int j = 1;j <= n;j++) { if(vis[j]) continue; if(dis[j] > dis[k]+a[j][k]) dis[j] = dis[k]+a[j][k]; } } cout << 2*dis[d] << endl; } return 0; }
1196.直接判断。
#include <bits/stdc++.h> using namespace std; int n; int main() { ios::sync_with_stdio(false); while(cin >> n) { if(n <= 1000) cout << "XiaoZhen" << endl; else if(n < 10000) cout << "Zh0ngshen" << endl; else cout << "DaNuo" << endl; } return 0; }
1197.直接判断。
#include <bits/stdc++.h> using namespace std; string s; int main() { ios::sync_with_stdio(false); while(cin >> s) { if(s == "v8") cout << "SingleDog&YangRouHuoGuo" << endl; else if(s == "qsqx") cout << "Couple&Program" << endl; else cout << "SingleDog&GoodGoodStud" << endl; } return 0; }
1198.递推,找公式。
#include <bits/stdc++.h> using namespace std; long long a[10000005]; int n; int main() { ios::sync_with_stdio(false); a[0] = 1; a[1] = 2; for(int i = 2;i <= 10000000;i++) a[i] = a[i-1]+2*(i-1); while(cin >> n) cout << a[n] << endl; return 0; }
1199.圆排列,除数取模不好处理,只要用在乘的时候抵消就可以了。
#include <bits/stdc++.h> using namespace std; long long n,m,p; int main() { ios::sync_with_stdio(false); while(cin >> n >> m >> p) { long long ans = 1; int flag = 0; for(int i = n-m+1;i <= n;i++) { if(!flag && i%m == 0) { ans = ans*i/m%p; flag = 1; } else ans = ans*i%p; } cout << ans << endl; } return 0; }
1200.递推,找公式。
#include <bits/stdc++.h> using namespace std; long long n; long long qpower(long long a,long long b,long long c) { a %= c; long long ans = 1; while(b) { if(b%2) ans = ans*a%c; a = a*a%c; b /= 2; } return ans; } int main() { ios::sync_with_stdio(false); while(cin >> n) cout << ((qpower(2,n,2097151)-1)*2+2097151)%2097151 << endl; return 0; }
1201.素数筛。
#include <bits/stdc++.h> using namespace std; int vis[1000005] = {0},prime[1000005],num[105] = {0}; long long n; int main() { int cnt = 0; for(int i = 2;i < 1000005;i++) { if(!vis[i]) prime[++cnt] = i; for(int j = 1;i*prime[j] < 1000005 && j <= cnt;j++) { vis[prime[j]*i] = 1; if(!(i%prime[j])) break; } } for(int i = 1;i <= 100;i++) { for(int j = 0;j <= i;j++) num[i] += (j+1)*(i-j+1); } while(~scanf("%lld",&n)) { long long ans = 1; for(int i = 1;(long long)prime[i]*prime[i] <= n;i++) { if(n%prime[i] == 0) { int t = 0; while(n%prime[i] == 0) { t++; n /= prime[i]; } ans *= num[t]; } } if(n != 1) ans *= 4; printf("%lld\n",ans); } return 0; }
1202.最短路构造虚点。
#include<bits/stdc++.h> using namespace std; struct xx { int to; long long w; xx(int a,long long b):to(a),w(b){}; friend bool operator <(xx X,xx Y) { return X.w > Y.w; } }; vector<xx> v[16005]; int n,m,r,h[105][105]; long long dis[16005]; bool vis[16005],has[105]; void add(int a,int b,int x) { v[a].push_back(xx(b,x)); v[b].push_back(xx(a,x)); } void dij(int beg) { priority_queue<xx> q; memset(dis,0x3f,sizeof(dis)); memset(vis,0,sizeof(vis)); dis[beg] = 0; q.push(xx(beg,0)); while(!q.empty()) { int now = q.top().to; q.pop(); if(vis[now]) continue; vis[now] = 1; for(int i = 0;i < v[now].size();i++) { int tt = v[now][i].to,ww = v[now][i].w; if(!vis[tt] && dis[now]+ww < dis[tt]) { dis[tt] = dis[now]+ww; q.push(xx(tt,dis[tt])); } } } } int main() { ios::sync_with_stdio(false); int T; cin >> T; while(T--) { for(int i = 1;i <= 16000;i++) v[i].clear(); cin >> n >> m >> r; for(int i = 1;i <= n;i++) { for(int j = 1;j <= m;j++) cin >> h[i][j]; } for(int i = 1;i <= n;i++) { for(int j = 1;j <= m;j++) { if(i+1 <= n) add(105*i+j,105*i+j+105,2*(h[i][j]+h[i+1][j])); if(j+1 <= m) add(105*i+j,105*i+j+1,2*(h[i][j]+h[i][j+1])); } } for(int k = 1;k <= r;k++) { memset(has,0,sizeof(has)); int ax,ay,bx,by,t,kk; cin >> ax >> ay >> bx >> by >> t >> kk; for(int i = ax;i <= bx;i++) { for(int j = ay;j <= by;j++) { add(11000+105*k+h[i][j],105*i+j,t); v[12500+105*k+h[i][j]].push_back(xx(105*i+j,0)); v[105*i+j].push_back(xx(14000+105*k+h[i][j],0)); has[h[i][j]] = 1; } } for(int i = 0;i <= 100;i++) { if(!has[i]) continue; for(int j = i+1;j <= min(i+kk,100);j++) { if(!has[j]) continue; add(12500+105*k+i,14000+105*k+j,2*t); add(14000+105*k+i,12500+105*k+j,2*t); } } } int sx,sy,ox,oy; cin >> sx >> sy >> ox >> oy; dij(105*sx+sy); cout << dis[105*ox+oy]/2 << endl; } }
1203.状压dp。
#include<bits/stdc++.h> using namespace std; #define MOD 1000000007 int n,m,k,cnt,sta[1<<18],a[45][1<<18]; void dfs(int l,int now,int pre1,int pre2) { if(l == m) { sta[now] = 1; return; } for(int i = 0;i < k;i++) { if(i == pre1 && i == pre2) continue; dfs(l+1,(now<<3)|i,pre2,i); dfs(l+1,(now<<3)|(i+4),pre2,i); } } bool ok(int x) { int t = x%4; x >>= 3; int tt = x%4; if(t != tt) return 1; x >>= 3; int ttt = x%4; if(t != ttt) return 1; return 0; } int main() { ios::sync_with_stdio(false); while(cin >> n >> m >> k) { if(n < m) swap(n,m); memset(sta,0,sizeof(sta)); memset(a,0,sizeof(a)); cnt = 0; dfs(0,0,-1,-1); int endd = 1<<(3*m); for(int i = 0;i < endd;i++) { if(!sta[i]) continue; int flag = 0; for(int j = 0;j < m;j++) { if(i&(4<<(j*3))) flag = 1; } if(!flag) a[m][i] = 1; } for(int i = 1;i < n;i++) { for(int j = 0;j < m;j++) { int now = i*m+j+1; for(int l = 0;l < endd;l++) { if(a[now-1][l] == 0) continue; if((l&(4<<(j*3))) == 0 && (j < 2 || ok(l>>(3*j-6)))) a[now][l|(4<<(j*3))] = (a[now][l|(4<<(j*3))]+a[now-1][l])%MOD; for(int t = 0;t < k;t++) { if(t == (l>>(j*3))%4) continue; int tt = (l-(l&(7<<(j*3))))|(t<<(j*3)); if(j > 1 && !ok(tt>>(3*j-6))) continue; a[now][tt] = (a[now][tt]+a[now-1][l])%MOD; } } } } int t = n*m; int ans = 0; for(int i = 0;i < endd;i++) ans = (ans+a[t][i])%MOD; cout << ans << endl; } return 0; }
1204.大模拟的恐惧。
#include<bits/stdc++.h> using namespace std; int n,x1,x2,a[105][105] = {0},ok[105],vis[105]; double calcF() { double kin = 0,kout = 0; for(int i = 1;i <= n;i++) { for(int j = i+1;j <= n;j++) { if(ok[i] && ok[j]) kin += 2*a[i][j]; else if(ok[i] || ok[j]) kout += a[i][j]; } } return kin/(kin+kout); } double calcf(int x) { int t = ok[x]; ok[x] = 1; double t1 = calcF(); ok[x] = 0; double t2 = calcF(); ok[x] = t; return t1-t2; } void op1() { double maxx = -1e18; int pos = -1; for(int i = 1;i <= n;i++) { if(ok[i]) continue; int flag = 0; for(int j = 1;j <= n;j++) { if(ok[j] && a[i][j]) flag = 1; } if(!flag) continue; double t = calcf(i); if(t-maxx > 1e-6 || abs(t-maxx) <= 1e-6) { maxx = t; pos = max(pos,i); } } ok[pos] = 1; } void op2() { double minn = 1e18; int pos = -1; for(int i = 1;i <= n;i++) { if(!ok[i]) continue; double t = calcf(i); if(minn-t > 1e-6 || abs(minn-t) <= 1e-6) { minn = t; pos = max(pos,i); } } if(minn < 0) ok[pos] = 0; } bool isok() { for(int i = 1;i <= n;i++) { if(ok[i] && calcf(i) <= 0) return 0; if(ok[i]) continue; int flag = 0; for(int j = 1;j <= n;j++) { if(ok[j] && a[i][j]) flag = 1; } if(flag && calcf(i) >= 0) return 0; } return 1; } void op(int x) { ok[x] = 1; while(1) { op1(); op2(); if(isok()) return; } } int main() { //freopen("1.txt","r",stdin); ios::sync_with_stdio(); cin >> x1 >> x2; int x,y,z; while(cin >> x >> y >> z) { n = max(n,x); n = max(n,y); a[x][y] += z; a[y][x] += z; } memset(ok,0,sizeof(ok)); op(x1); if(ok[x1] && ok[x2]) { cout << "YES" << endl; return 0; } memset(ok,0,sizeof(ok)); op(x2); if(ok[x1] && ok[x2]) { cout << "YES" << endl; return 0; } cout << "NO" << endl; return 0; }
1205.构造x为10。
#include<bits/stdc++.h> using namespace std; string s; stack<char> ss; int main() { ios::sync_with_stdio(false); while(cin >> s) { if(s.length() == 1) { cout << "1 10" << endl; cout << 0 << " " << s[0] << endl; continue; } for(int i = 0;i < s.length();i++) ss.push(s[i]); cout << s.length()-1 << " " << 10 << endl; cout << ss.top(); ss.pop(); while(!ss.empty()) { cout << " " << ss.top();; ss.pop(); } cout << endl; } return 0; }
1206.等比求和推。
#include<bits/stdc++.h> #define LL long long using namespace std; string s; int main() { ios::sync_with_stdio(false); while(cin >> s) { LL t = 0,x = 0,y = 0; int i = 0,len = s.length(); int a = 0,b = 0; for(;i < len && s[i] != '.';i++) t = t*10+s[i]-'0'; i++; for(;i < len && s[i] != '_';i++) { x = x*10+s[i]-'0'; a++; } i++; y = x; for(;i < len && s[i] != '.';i++) { y = y*10+s[i]-'0'; b++; } LL sub,mom,z = 0; if(a == 0 && b != 0) { while(b--) z = z*10+9; LL g = __gcd(y,z); sub = y/g,mom = z/g; } else if(a == 0 && b == 0) { sub = 0; mom = 1; } else if(b == 0) { z = 1; while(a--) z *= 10; LL g = __gcd(x,z); sub = x/g,mom = z/g; } else { y -= x; while(b--) z = z*10+9; while(a--) z *= 10; LL g = __gcd(y,z); sub = y/g,mom = z/g; } sub += t*mom; cout << sub << "/" << mom << endl; } return 0; }
1207.dp,过程中有个累和优化。
#include<bits/stdc++.h> #define MOD 1000000007 using namespace std; int n,l,r,sum[10005],t[10005]; int main() { ios::sync_with_stdio(false); while(cin >> n >> l >> r) { memset(sum,0,sizeof(sum)); memset(t,0,sizeof(t)); t[0] = 1; sum[0] = 1; while(n--) { int c,a; cin >> c >> a; for(int i = 0;i+c <= r;i++) { t[i+c] = (t[i]+t[i+c])%MOD; int tt = i+(a+1)*c; if(tt <= r) t[tt] = (t[tt]-sum[i]+MOD)%MOD; } memcpy(sum,t,(r+1)*sizeof(int)); } for(int i = l+1;i <= r;i++) sum[i] = (sum[i-1]+sum[i])%MOD; cout << sum[r] << endl; } return 0; }
1208.每次少k-1个瓶盖,推公式。
#include<bits/stdc++.h> #define MOD 1000000007 #define LL long long using namespace std; int a,b,k; LL qmod(LL a, LL b, LL c) { LL ans = 1; a = a%c; while(b) { if(b&1) ans = ans*a%c; b >>= 1; a = a*a%c; } return ans; } int main() { ios::sync_with_stdio(false); while(cin >> a >> b >> k) { LL x = qmod(a,b,k-1); if(x == 0) x = k-1; cout << (qmod(a,b,MOD)-x+MOD)%MOD*qmod(k-1,MOD-2,MOD)%MOD << endl; } return 0; }
1209.dp,f[i] = sum[i-1]*2/i+i。
#include<bits/stdc++.h> using namespace std; int n; double f[1000005],sum[1000005]; int main() { ios::sync_with_stdio(); f[0] = 0; sum[0] = 0; for(int i = 1;i <= 1000000;i++) { f[i] = 2*sum[i-1]/i+i; sum[i] = sum[i-1]+f[i]; } int T; cin >> T; while(T--) { cin >> n; cout << f[n] << endl; } return 0; }
1210.
#include<bits/stdc++.h> #define MOD 19260817 using namespace std; int n,q,a[55]; long long euler(long long n) { long long ans = 1; for(int i = 2;(long long)i*i <= n;i++) { if(n%i == 0) { n /= i; ans *= i-1; while(n%i == 0) { n /= i; ans *= i; } } } if(n > 1) ans *= n-1; return ans; } int main() { while(~scanf("%d",&n)) { for(int i = 1;i <= n;i++) { int x; scanf("%d",&x); a[i] = euler(x); } scanf("%d",&q); while(q--) { long long ans = 1; int x; scanf("%d",&x); for(int i = 1;i <= n;i++) ans = ans*(__gcd(x-1,a[i])+1)%MOD; printf("%lld\n",ans); } } return 0; }
1211.首项系数为1,根肯定为整数,且为an因子,找个大素数取模防止溢出。
#include<bits/stdc++.h> #define MOD 1000000007 using namespace std; int n,a[25]; long long qpower(long long a, long long b, long long c) { long long ans = 1; a = a%c; while(b) { if(b%2) ans = ans*a%c; a = a*a%c; b /= 2; } return ans; } bool ok(long long x) { long long t = 0; for(int i = 0;i <= n;i++) t = (t+a[i]*qpower(x,n-i,MOD)+MOD)%MOD; return t == 0; } int main() { ios::sync_with_stdio(0); a[0] = 1; while(cin >> n) { for(int i = 1;i <= n;i++) cin >> a[i]; long long x = abs(a[n]),ans = 0; for(long long i = 1;i*i <= x;i++) { if(x%i) continue; if(ok(i)) ans += i; if(ok(-i)) ans -= i; if(i*i == x) continue; if(ok(x/i)) ans += x/i; if(ok(-x/i)) ans -= x/i; } cout << fixed << setprecision(2) << (double)ans << endl; } return 0; }
1213.对m排序,双指针维护m符合的序列,树状数组维护w。
#include<bits/stdc++.h> using namespace std; int n,X,Y,tree[100005]; inline int lowbitt(int x) { return x&-x; } void add(int pos,int x) { while(pos <= 100000) { tree[pos] += x; pos += lowbitt(pos); } } int getsum(int pos) { int ans = 0; while(pos > 0) { ans += tree[pos]; pos -= lowbitt(pos); } return ans; } struct xx { int x,y; friend bool operator<(xx a,xx b) { return a.x < b.x; } }a[100005]; int main() { ios::sync_with_stdio(false); while(~scanf("%d%d%d",&n,&X,&Y)) { memset(tree,0,sizeof(tree)); for(int i = 1;i <= n;i++) scanf("%d",&a[i].x); for(int i = 1;i <= n;i++) scanf("%d",&a[i].y); sort(a+1,a+1+n); int now = 1,r = 1; long long ans = 0; for(int i = n;i >= 1;i--) { while(a[r].x <= X-a[i].x) r++; while(now > i) { --now; add(a[now].y,-1); } while(now < i && now < r) { add(a[now].y,1); now++; } ans += getsum(Y-a[i].y); } printf("%lld\n",ans); } return 0; }
1216.dfs序+划分树,或dfs序+主席树。
#include<bits/stdc++.h> #define N 100005 using namespace std; int n,m,cnt,l[N],r[N],pos[N]; int a[N]; vector<int> v[N]; void dfs(int now,int pre) { l[now] = ++cnt; pos[cnt] = now; for(int i = 0;i < v[now].size();i++) { int t = v[now][i]; if(t == pre) continue; dfs(t,now); } r[now] = cnt; } int tree[20][N],sorted[N],toleft[20][N]; void build(int l,int r,int dep) { if(l == r)return; int mid = (l+r)/2,same = mid-l+1; for(int i = l;i <= r;i++) { if(tree[dep][i] < sorted[mid]) same--; } int lpos = l,rpos = mid+1; for(int i = l;i <= r;i++) { if(tree[dep][i] < sorted[mid]) tree[dep+1][lpos++] = tree[dep][i]; else if(tree[dep][i] == sorted[mid] && same > 0) { tree[dep+1][lpos++] = tree[dep][i]; same--; } else tree[dep+1][rpos++] = tree[dep][i]; toleft[dep][i] = toleft[dep][l-1]+lpos-l; } build(l,mid,dep+1); build(mid+1,r,dep+1); } int query(int l,int r,int ql,int qr,int dep,int k) { if(ql == qr) return tree[dep][ql]; int mid = (l+r)/2,cnt = toleft[dep][qr]-toleft[dep][ql-1]; if(cnt >= k) { int ll = l+toleft[dep][ql-1]-toleft[dep][l-1],rr = ll+cnt-1; return query(l,mid,ll,rr,dep+1,k); } else { int rr = qr+toleft[dep][r]-toleft[dep][qr],ll = rr-(qr-ql-cnt); return query(mid+1,r,ll,rr,dep+1,k-cnt); } } int main() { while(~scanf("%d",&n)) { for(int i = 1;i <= n;i++) scanf("%d",&a[i]); for(int i = 1;i <= n;i++) v[i].clear(); cnt = 0; for(int i = 1;i < n;i++) { int x,y; scanf("%d%d",&x,&y); v[x].push_back(y); v[y].push_back(x); } dfs(1,-1); for(int i = 1;i <= n;i++) sorted[i] = tree[0][i] = a[pos[i]]; sort(sorted+1,sorted+n+1); build(1,n,0); scanf("%d",&m); while(m--) { int x,y; scanf("%d%d",&x,&y); printf("%d\n",query(1,n,l[x],r[x],0,y)); } } return 0; }
1226.待补。
1127.lucas+中国剩余。
#include<bits/stdc++.h> using namespace std; int n; long long a[100005]; long long qmod(long long a,long long b,long long c) { long long ans = 1; a = a%c; while(b) { if(b%2) ans = (ans*a)%c; a = (a*a)%c; b /= 2; } return ans; } long long c(long long m,long long n,long long MOD) { if(m < n) return 0; if(m == n) return 1; if(n > m-n) n = m-n; long long mm = 1,nn = 1; for(long long i = 0;i < n;i++) { mm = mm*(m-i)%MOD; nn = nn*(n-i)%MOD; } return mm*qmod(nn,MOD-2,MOD)%MOD; } long long lucas(long long m,long long n,long long MOD) { long long ans = 1; while(m && n && ans) { ans = ans%MOD*c(m%MOD,n%MOD,MOD)%MOD; n /= MOD; m /= MOD; } return ans; } long long e_gcd(long long a,long long b,long long &x,long long &y) { if(!b) { x = 1; y = 0; return a; } long long d = e_gcd(b,a%b,y,x); y -= a/b*x; return d; } long long solve(long long *m,long long *a,long long n) { long long M = m[1],A = a[1],x,y; for(int i = 2;i <= n;i++) { long long d = e_gcd(M,m[i],x,y); if((a[i]-A)%d) return -1; x = (a[i]-A)/d*x%(m[i]/d); A += x*M; M = M/d*m[i]; A %= M; } if(A < 0) A += M; return A; } int main() { int T; scanf("%d",&T); while(T--) { scanf("%d",&n); for(int i = 1;i <= n;i++) scanf("%lld",&a[i]); long long t1 = 0,t2 = 0,t3 = 0; for(int i = 1;i <= n;i++) { t1 = (t1+lucas(n-1,i-1,7)*a[i])%7; t2 = (t2+lucas(n-1,i-1,11)*a[i])%11; t3 = (t3+lucas(n-1,i-1,13)*a[i])%13; } long long a[4],m[4]; a[1] = t1; a[2] = t2; a[3] = t3; m[1] = 7; m[2] = 11; m[3] = 13; printf("%lld\n",solve(m,a,3)); } return 0; }
1129.len-串和反串的LCS。
#include<bits/stdc++.h> using namespace std; int dp[5005][5005]; char a[5005],b[5005]; int main() { ios::sync_with_stdio(false); int T; scanf("%d",&T); while(T--) { scanf("%s",&a); int len = strlen(a); for(int i = 0;i < len;i++) b[i] = a[len-i-1]; memset(dp,0,sizeof(dp)); for(int i = 1;i <= len;i++) { for(int j = 1;j <= len;j++) { if(a[i-1] == b[j-1]) dp[i][j] = dp[i-1][j-1]+1; else dp[i][j] = max(dp[i-1][j],dp[i][j-1]); } } printf("%d\n",len-dp[len][len]); } return 0; }
1233.转化为LIS,nlogn。
#include<bits/stdc++.h> using namespace std; int n,a[100005],b[100005],mp[100005]; int main() { ios::sync_with_stdio(0); int T; scanf("%d",&T); while(T--) { scanf("%d",&n); for(int i = 1;i <= n;i++) scanf("%d",&a[i]); for(int i = 1;i <= n;i++) scanf("%d",&b[i]); for(int i = 1;i <= n;i++) mp[b[i]] = i; for(int i = 1;i <= n;i++) a[i] = mp[a[i]]; b[1] = a[1]; int len = 1; for(int i = 2;i <= n;i++) { int t = lower_bound(b+1,b+len+1,a[i])-b; b[t] = a[i]; if(t == len+1) len++; } printf("%d\n",len); } return 0; }
1234.打表会发现规律。
#include<bits/stdc++.h> using namespace std; int n; double a[25],b[25],R; int main() { ios::sync_with_stdio(0); cin >> n; if(n == 0) { cout << "0.00" << endl; return 0; } for(int i = 1;i <= n;i++) cin >> a[i]; cin >> R; sort(a+1,a+1+n); reverse(a+1,a+1+n); int l = 1,r = n,cnt = 1; while(l <= r) { if(cnt%2) b[r--] = a[cnt++]; else b[l++] = a[cnt++]; } double ans = b[1]+b[n]; for(int i = 1;i < n;i++) ans += 2*sqrt(R*(b[i]+b[i+1]-R)); cout << fixed << setprecision(2) << ans << endl; return 0; }
1237.二分轮数。
#include<bits/stdc++.h> using namespace std; int n,maxx = 0,cnt[1000005] = {0}; bool ok(int x) { if(x < maxx) return 0; if(x-maxx > 30) return 1; int now = 1; for(int i = 0;i <= x;i++) { if(now > 1e6) break; if(cnt[x-i] > now) return 0; now -= cnt[x-i]; now *= 2; } return 1; } int main() { scanf("%d",&n); for(int i = 1;i <= n;i++) { int x; scanf("%d",&x); cnt[x]++; maxx = max(maxx,x); } int l = 0,r = 1e6+50; while(l < r) { int mid = (l+r)/2; if(ok(mid)) r = mid; else l = mid+1; } printf("%d\n",l); return 0; }
1239.从高位往低位贪心,尽可能将1和并成偶数,维护每个可以划分的位置。
#include<bits/stdc++.h> using namespace std; int n,k,a[100005][35],ok[100005][35]; int main() { int T; scanf("%d",&T); while(T--) { scanf("%d%d",&n,&k); for(int i = 1;i <= n;i++) { int x; scanf("%d",&x); for(int j = 1;j <= 30;j++) { a[i][j] = x%2; x /= 2; } } for(int i = 1;i <= n;i++) ok[i][31] = 1; int ans = 0; for(int j = 30;j >= 1;j--) { int cnt = 0,now = 0; for(int i = 1;i <= n;i++) { now ^= a[i][j]; if(now == 0 && ok[i][j+1]) { ok[i][j] = 1; cnt++; } else ok[i][j] = 0; } if(cnt < k || now == 1) { ans += (1<<(j-1)); for(int i = 1;i <= n;i++) ok[i][j] = ok[i][j+1]; } } cout << ans << endl; } return 0; }
1240.贪心找大于等于且最小的。
#include<bits/stdc++.h> using namespace std; int n,a[100005]; int main() { while(~scanf("%d",&n)) { multiset<int> s; for(int i = 1;i <= n;i++) { int x; scanf("%d",&x); s.insert(x); } for(int i = 1;i <= n;i++) scanf("%d",&a[i]); int ans = 0; for(int i = 1;i <= n;i++) { auto it = s.lower_bound(a[i]); if(it != s.begin()) { it--; ans++; s.erase(it); } } if(ans) printf("%d\n",ans); else printf("Godv too strong\n"); } return 0; }
1241.dp[i][j]表示前i个时刻,j个芯片最大的rp。
#include<bits/stdc++.h> using namespace std; int n,m,a[505],dp[505][505],x[505][505]; int main() { ios::sync_with_stdio(0); int T; cin >> T; while(T--) { cin >> n >> m; for(int i = 1;i <= n;i++) cin >> a[i]; for(int i = 1;i <= n;i++) { int minn = 555; for(int j = i;j <= n;j++) { minn = min(minn,a[j]); x[i][j] = minn; } } memset(dp,0,sizeof(dp)); for(int j = 1;j <= m;j++) { for(int i = n;i >= 1;i--) { for(int k = i;k >= 1;k--) dp[i][j] = max(dp[i][j],dp[k-1][j-1]+(i-k+1)*x[k][i]); } for(int i = 1;i <= n;i++) dp[i][j] = max(dp[i][j],dp[i-1][j]); } cout << dp[n][m] << endl; } return 0; }
*1242.待补。
1243.移项,开根号。
#include<bits/stdc++.h> using namespace std; long long z,ans; void ok(long long x) { long long endd = sqrt(x/2); for(long long i = 1;i <= endd;i++) { long long a = i*i,b = x-a; long long t = sqrt(b); if(t*t == b && __gcd(a,b) == 1 && a != b) ans++; } } int main() { int T; cin >> T; while(T--) { cin >> z; ans = 1; long long endd = sqrt(2*z); for(long long i = 1;i <= endd;i++) { if(2*z%i) continue; ok(i); ok(2*z/i); } cout << ans*4 << endl; } return 0; }
*1244.待补。
1245.数位dp+kmp。
#include<bits/stdc++.h> using namespace std; int a[25],b[25],x[25],cnt1,cnt2; long long n,m,dp[25][25]; long long dfs(int now1,int now2,int limit) { if(now2 == 0) return 0; if(now1 == 0) return 1; if(!limit && dp[now1][now2] != -1) return dp[now1][now2]; int endd = limit?a[now1]:9; long long ans = 0; for(int i = endd;i >= 0;i--) { int t = now2; while(b[t] != i && t != cnt2) t = x[t]; if(b[t] == i) t--; ans += dfs(now1-1,t,limit && i == endd); } if(!limit) dp[now1][now2] = ans; return ans; } int main() { ios::sync_with_stdio(0); int T; cin >> T; while(T--) { cin >> n >> m; cnt1 = 0; cnt2 = 0; while(n) { a[++cnt1] = n%10; n /= 10; } while(m) { b[++cnt2] = m%10; m /= 10; } int i = cnt2,j = cnt2+1; x[cnt2] = cnt2+1; while(i >= 1) { if(j == cnt2+1 || b[i] == b[j]) x[--i] = --j; else j = x[j]; } x[cnt2] = cnt2; memset(dp,-1,sizeof(dp)); cout << dfs(cnt1,cnt2,1)-1 << endl; } return 0; }
*1247.待补。
*1248.待补。
*1250.待补。
1254.高精度。
#include<bits/stdc++.h> using namespace std; string s1,s2,s3,s4; int compare(string str1,string str2) { if(str1.length() > str2.length()) return 1; else if(str1.length() < str2.length()) return -1; else return str1.compare(str2); } string sub(string str1,string str2) { string str; int flag = 0; if(compare(str1,str2) < 0) { flag = 1; swap(str1,str2); } int tmp = str1.length()-str2.length(),cf = 0; for(int i = str2.length()-1;i >= 0;i--) { if(str1[tmp+i] < str2[i]+cf) { str = char(str1[tmp+i]-str2[i]-cf+'0'+10)+str; cf = 1; } else { str = char(str1[tmp+i]-str2[i]-cf+'0')+str; cf = 0; } } for(int i = tmp-1;i >= 0;i--) { if(str1[i]-cf >= '0') { str = char(str1[i]-cf)+str; cf = 0; } else { str = char(str1[i]-cf+10)+str; cf = 1; } } str.erase(0,str.find_first_not_of('0')); if(str.empty()) str = "0"; if(flag) str = "-"+str; return str; } int main() { cin >> s1 >> s2 >> s3 >> s4; string t = sub(s2,s1),y = sub(s4,s3); int x = compare(t,y); if(x > 0) cout << "Ting" << endl; else if(x < 0) cout << "Yu" << endl; else cout << "Excellent" << endl; return 0; }
1255.进制转化。
#include<bits/stdc++.h> using namespace std; string s; int main() { while(getline(cin,s)) { stringstream ss(s); char c; int x,y,z; ss >> c >> x >> c >> y >> c >> z; cout << "#" << hex << uppercase << setw(2) << setfill('0') << x << setw(2) << setfill('0') << y << setw(2) << setfill('0') << z << endl; } return 0; }
1256.处理每一位。
#include<bits/stdc++.h> using namespace std; int n; string yi[5] = {"","I","X","C","M"}; string wu[5] = {"","V","L","D"}; int main() { ios::sync_with_stdio(0); while(cin >> n) { string s = ""; int now = 1; while(n) { int t = n%10; n /= 10; if(t <= 3) { while(t--) s = yi[now]+s; } else if(t <= 5) { s = wu[now]+s; if(t == 4) s = yi[now]+s; } else if(t <= 8) { t -= 5; while(t--) s = yi[now]+s; s = wu[now]+s; } else s = yi[now]+yi[now+1]+s; now++; } cout << s << endl; } return 0; }
1257.两个绝对值的最大值可转化为非绝对值的形式,维护两个最小值。
#include<bits/stdc++.h> using namespace std; int n; struct xx { int x,y; friend bool operator<(xx a,xx b) { return a.x < b.x; } }a[1000005]; int main() { ios::sync_with_stdio(0); int T; scanf("%d",&T); while(T--) { scanf("%d",&n); for(int i = 1;i <= n;i++) scanf("%d%d",&a[i].x,&a[i].y); sort(a+1,a+1+n); long long ans = 0,minn1 = 1e18,minn2 = 1e18; for(int i = 1;i <= n;i++) { ans = max(ans,max(a[i].x+a[i].y-minn1,a[i].x-a[i].y-minn2)); minn1 = min(minn1,(long long)a[i].x+a[i].y); minn2 = min(minn2,(long long)a[i].x-a[i].y); } cout << ans << endl; } return 0; }
1259.n-1。
#include<bits/stdc++.h> using namespace std; int n; int main() { ios::sync_with_stdio(0); int T; cin >> T; while(T--) { cin >> n; cout << n-1 << endl; } return 0; }
1260.加权平均值。
#include<bits/stdc++.h> using namespace std; int n; map<string,double> mp1; map<string,int> mp2; int main() { ios::sync_with_stdio(0); cin >> n; for(int i = 1;i <= n;i++) { string s; double x; int y; cin >> s >> x >> y; if(mp2.count(s)) { mp2[s] = max(mp2[s],y); } else { mp1[s] = x; mp2[s] = y; } } double sum1 = 0,sum2 = 0,sum3; for(auto it = mp1.begin();it != mp1.end();it++) { int t = mp2[it->first]; sum1 += t*it->second; if(t < 60) sum2 += 0; else if(t < 63) sum2 += 1*it->second; else if(t < 66) sum2 += 1.5*it->second; else if(t < 69) sum2 += 1.7*it->second; else if(t < 72) sum2 += 2*it->second; else if(t < 75) sum2 += 2.3*it->second; else if(t < 78) sum2 += 2.7*it->second; else if(t < 82) sum2 += 3*it->second; else if(t < 85) sum2 += 3.3*it->second; else if(t < 90) sum2 += 3.7*it->second; else sum2 += 4*it->second; sum3 += it->second; } cout << fixed << setprecision(1) << sum1/sum3 << endl; cout << fixed << setprecision(2) << sum2/sum3 << endl; return 0; }
1261.带属性的并查集。
#include<bits/stdc++.h> using namespace std; int n,m,a[100005],pre[100005]; int findd(int x) { if(x == pre[x]) return x; int t = findd(pre[x]); a[x] ^= a[pre[x]]; pre[x] = t; return pre[x]; } void join(int x,int y) { int xx = findd(x),yy = findd(y); if(xx != yy) { a[xx] = a[x]^a[y]^1; pre[xx] = yy; } } int main() { ios::sync_with_stdio(0); while(~scanf("%d%d",&n,&m)) { memset(a,0,sizeof(a)); for(int i = 1;i <= n;i++) pre[i] = i; for(int i = 1;i <= m;i++) { int t,x,y; scanf("%d%d%d",&t,&x,&y); if(t) { int xx = findd(x),yy = findd(y); if(xx != yy) printf("Not sure yet.\n"); else if(a[x] == a[y]) printf("In the same category.\n"); else printf("In different category.\n"); } else join(x,y); } } return 0; }
1262.先求Q的前缀和后缀和。
#include<bits/stdc++.h> using namespace std; string s; long long l[100005] = {0},r[100005] = {0}; int main() { ios::sync_with_stdio(0); cin >> s; int n = s.length(); s = " "+s; for(int i = 1;i <= n;i++) l[i] = l[i-1]+(s[i] == 'Q'); for(int i = n;i >= 1;i--) r[i] = r[i+1]+(s[i] == 'Q'); long long ans = 0; for(int i = 1;i <= n;i++) { if(s[i] == 'A') ans += l[i-1]*r[i+1]; } cout << ans << endl; return 0; }
1263.用r来分隔g和b,注意r的个数限制,以及r只有两个时g和b的限制,以及n=1的特例。
#include<bits/stdc++.h> using namespace std; int n; int main() { ios::sync_with_stdio(0); int T; cin >> T; while(T--) { cin >> n; int r = 0,g = 0,b = 0; for(int i = 1;i <= 2;i++) { string s; cin >> s; for(int j = 0;j < n;j++) { if(s[j] == 'R') r++; else if(s[j] == 'G') g++; else b++; } } if(n == 1 && r != 2 && (!g || !b) || n > 1 && r <= n && (!g || !b || r == 2 && g%2 == 1 && b%2 == 1 || r > 2)) cout << "YES" << endl; else cout << "NO" << endl; } return 0; }
1264.二进制输出。
#include<bits/stdc++.h> using namespace std; int a[105]; long long n; int main() { ios::sync_with_stdio(0); while(cin >> n) { memset(a,0,sizeof(a)); int now = 100; while(n) { a[now--] = n%2; n /= 2; } for(int i = 1;i <= 100;i++) cout << char(a[i]?'R':'G'); cout << endl; } return 0; }
*1266.待补。
1269.bfs。
#include<bits/stdc++.h> using namespace std; string s[15]; bool vis[15][15][3] = {0}; int dis[15][15][3]; int dx[4] = {-1,1,0,0}; int dy[4] = {0,0,-1,1}; struct xxx { int x,y,b; xxx(){}; xxx(int xx,int yy,int bb = 0):x(xx),y(yy),b(bb){}; }; int main() { ios::sync_with_stdio(0); memset(dis,0x3f,sizeof(dis)); for(int i = 1;i <= 10;i++) { cin >> s[i]; s[i] = " "+s[i]; } queue<xxx> q; int endx,endy; for(int i = 1;i <= 10;i++) { for(int j = 1;j <= 10;j++) { if(s[i][j] == 'S') { q.push(xxx(i,j,0)); vis[i][j][0] = 1; dis[i][j][0] = 0; } else if(s[i][j] == 'E') { endx = i; endy = j; } } } while(!q.empty()) { int x = q.front().x,y = q.front().y,b = q.front().b; q.pop(); if(x == endx && y == endy) break; for(int i = 0;i < 4;i++) { int xx = x+dx[i],yy = y+dy[i],bb = b; if(xx < 1 || xx > 10 || yy < 1 || yy > 10) continue; if(s[xx][yy] == 'r' && (bb == 0 || bb == 2)) continue; if(s[xx][yy] != 'r' && !vis[xx][yy][bb]) { if(bb == 0 && s[xx][yy] == 'B') bb = 1; vis[xx][yy][bb] = 1; dis[xx][yy][bb] = min(dis[xx][yy][bb],dis[x][y][b]+1); q.push(xxx(xx,yy,bb)); } else if(s[xx][yy] == 'r' && bb == 1 && !vis[xx][yy][2]) { vis[xx][yy][2] = 1; dis[xx][yy][2] = min(dis[xx][yy][2],dis[x][y][b]+1); q.push(xxx(xx,yy,2)); } } } int ans = min(min(dis[endx][endy][0],dis[endx][endy][1]),dis[endx][endy][2]); if(ans != 0x3f3f3f3f) cout << ans << endl; else cout << -1 << endl; return 0; }
1272.排序和去重。
#include<bits/stdc++.h> using namespace std; int n,a[1005],b[1005],c[10005] = {0}; int main() { ios::sync_with_stdio(0); cin >> n; for(int i = 1;i <= n;i++) cin >> a[i]; for(int i = 1;i <= n;i++) b[i] = a[i]; sort(b+1,b+1+n); cout << b[1]; for(int i = 2;i <= n;i++) cout << " " << b[i]; cout << endl; int maxx = b[n-1],minn = b[2]; for(int i = 1;i <= n;i++) b[i] = a[i]; vector<int> v; map<int,int> mp; for(int i = 1;i <= n;i++) { if(mp.count(b[i])) continue; v.push_back(b[i]); mp[b[i]] = 1; } cout << v[0]; for(int i = 1;i < v.size();i++) cout << " " << v[i]; cout << endl; cout << maxx << " " << minn << endl; for(int i = 1;i <= n;i++) c[a[i]]++; maxx = 0; for(int i = 0;i <= 10000;i++) maxx = max(maxx,c[i]); v.clear(); for(int i = 0;i <= 10000;i++) { if(c[i] == maxx) v.push_back(i); } cout << v[0]; for(int i = 1;i < v.size();i++) cout << " " << v[i]; cout << endl; return 0; }
1273.不断交换到对应下标位置。
#include<bits/stdc++.h> using namespace std; int n,b[100005]; struct xx { int x,pos; friend bool operator<(xx a,xx b) { return a.x < b.x; } }a[100005]; int main() { ios::sync_with_stdio(0); int T; cin >> T; while(T--) { cin >> n; for(int i = 1;i <= n;i++) { cin >> a[i].x; a[i].pos = i; } sort(a+1,a+1+n); for(int i = 1;i <= n;i++) b[a[i].pos] = i; int ans = 0; for(int i = 1;i <= n;i++) { while(b[i] != i) { ans++; swap(b[i],b[b[i]]); } } cout << ans << endl; } return 0; }
1274.推公式。
#include<bits/stdc++.h> using namespace std; int n; int main() { ios::sync_with_stdio(0); int T; cin >> T; while(T--) { cin >> n; cout << (n-1)*(n-2)/2 << endl; } return 0; }
1275.枚举左下,右上两个点。
#include<bits/stdc++.h> using namespace std; int n,a[105][105]; int main() { ios::sync_with_stdio(0); int T; cin >> T; while(T--) { memset(a,0,sizeof(a)); cin >> n; for(int i = 1;i <= n;i++) { int x,y; cin >> x >> y; a[x][y] = 1; } int ans = 0; for(int i = 0;i <= 100;i++) { for(int j = 0;j <= 100;j++) { if(!a[i][j]) continue; int endd = min(100-i,100-j); for(int k = 1;k <= endd;k++) { if(a[i+k][j] && a[i][j+k] && a[i+k][j+k]) ans++; } } } cout << ans << endl; } return 0; }
1276.维护个前缀和累计值。
#include<bits/stdc++.h> using namespace std; int n,m,a[100005] = {0}; int main() { ios::sync_with_stdio(0); while(cin >> n >> m) { memset(a,0,sizeof(a)); for(int i = 1;i <= m;i++) { int x; cin >> x; a[1]++; a[x+1]--; } for(int i = 1;i <= n;i++) a[i] += a[i-1]; for(int i = 1;i <= n;i++) cout << a[i] << endl; } return 0; }
1277.判断旋转的9种情况是否可行。
#include<bits/stdc++.h> using namespace std; int a[25],b[25]; int pan[6][4] = {{1,2,3,4},{5,6,7,8},{9,10,11,12},{13,14,15,16},{17,18,19,20},{21,22,23,24}}; int zhuan[3][8] = {{1,3,5,7,9,11,24,22},{13,14,5,6,17,18,21,22},{3,4,17,19,10,9,16,14}}; bool ok() { for(int i = 0;i < 6;i++) { if(!(b[pan[i][0]] == b[pan[i][1]] && b[pan[i][1]] == b[pan[i][2]] && b[pan[i][2]] == b[pan[i][3]])) return 0; } return 1; } int main() { ios::sync_with_stdio(0); while(cin >> a[1]) { int flag = 0; for(int i = 2;i <= 24;i++) cin >> a[i]; for(int i = 0;i < 3;i++) { for(int k = 1;k <= 3;k++) { for(int j = 1;j <= 24;j++) b[j] = a[j]; for(int j = 0;j < 8;j++) b[zhuan[i][j]] = a[zhuan[i][(j+2*k)%8]]; if(ok()) flag = 1; } } if(flag) cout << "YES" << endl; else cout << "NO" << endl; } return 0; }
1278.n小于等于100时,必为91。
#include<bits/stdc++.h> using namespace std; long long n; int main() { ios::sync_with_stdio(0); int T; scanf("%d",&T); while(T--) { scanf("%lld",&n); if(n > 100) printf("%lld\n",n-10); else printf("91\n"); } return 0; }
1281.f(n) = f(n-1)+f(n-2)+f(n-4),矩阵快速幂。
#include<bits/stdc++.h> #define MOD 1000000007 using namespace std; long long n; struct matrix { long long m[4][4]; }; matrix one = { 1,0,0,0, 0,1,0,0, 0,0,1,0, 0,0,0,1 }; matrix base = { 1,1,0,1, 1,0,0,0, 0,1,0,0, 0,0,1,0 }; matrix mul(matrix a, matrix b) { matrix tmp; for(int i = 0; i < 4;i++) { for(int j = 0; j < 4;j++) { tmp.m[i][j] = 0; for(int k = 0; k < 4;k++) tmp.m[i][j] = (tmp.m[i][j]+a.m[i][k]*b.m[k][j])%MOD; } } return tmp; } matrix maqower(matrix a,long long b) { matrix ans = one; while(b) { if(b%2) ans = mul(ans,a); a = mul(a,a); b /= 2; } return ans; } int main() { ios::sync_with_stdio(0); while(cin >> n) { if(n == 1) cout << 1 << endl; else if(n == 2) cout << 2 << endl; else if(n == 3) cout << 4 << endl; else if(n == 4) cout << 7 << endl; else { matrix ans = maqower(base,n-4); cout << (7*ans.m[0][0]+4*ans.m[0][1]+2*ans.m[0][2]+ans.m[0][3])%MOD << endl; } } return 0; }
1282.推公式。
#include<bits/stdc++.h> using namespace std; int n; int main() { ios::sync_with_stdio(0); int T; cin >> T; while(T--) { cin >> n; cout << n*(n-1)/2 << endl; } return 0; }
1283.从中位数开始向上发,使这n/2+1个人最小值最大。
#include<bits/stdc++.h> using namespace std; int n,m; long long a[100005]; int main() { ios::sync_with_stdio(0); while(cin >> n >> m) { for(int i = 1;i <= n;i++) cin >> a[i]; sort(a+1,a+1+n); reverse(a+1,a+1+n); int k = (n+1)/2,now = k; long long sum = 0; while(now > 1 && (a[now-1]-a[now])*(k-now+1)+sum <= m) { sum += (a[now-1]-a[now])*(k-now+1); now--; } m -= sum; cout << a[now]+m/(k-now+1) << endl; } return 0; }
1284.最大公约数。
#include<bits/stdc++.h> using namespace std; int a,b; int main() { ios::sync_with_stdio(0); while(cin >> a >> b) cout << __gcd(a,b) << endl; return 0; }
1285.简单推一下公式,记忆化dp。
#include<bits/stdc++.h> using namespace std; int n; double dp[505]; double dfs(int x) { if(dp[x] > -1e-9) return dp[x]; dp[x] = 0; for(int i = 1;i <= x;i++) { if(x%i == 0) dp[x] += 1.0/x; else dp[x] += (dfs(x%i)+1)/x; } double t = 1.0*x/n; dp[x] += (1-t)/t; return dp[x]; } int main() { ios::sync_with_stdio(0); while(cin >> n) { for(int i = 1;i <= n;i++) dp[i] = -1; double ans = 1; for(int i = 1;i <= n;i++) ans += dfs(i)/n; cout << fixed << setprecision(2) << ans << endl; } return 0; }
1286.dp或者规律。
#include<bits/stdc++.h> using namespace std; int n; int main() { int T; cin >> T; while(T--) { cin >> n; int endd = sqrt(n+0.1); long long ans = 0; for(int i = 2;i <= endd;i++) { while(n%i == 0) { ans += i-1; n /= i; } } if(n > 1) ans += n-1; cout << ans <<endl; } return 0; }
1284.二分,三人或以上相同=1-无人相同-两人相同,计算时注意精度问题。
#include<bits/stdc++.h> using namespace std; int n,ans[20] = {0,3,4,5,6,7,7,8,9,9,10}; double c[2550][2550]; void get_C(int maxn) { c[0][0] = 1; for(int i = 1;i <= maxn;i++) { c[i][0] = 1; for(int j = 1;j <= i;j++) c[i][j] = c[i-1][j]+c[i-1][j-1]; } } bool ok(int x) { if(x > 2*n) return 1; double t1 = 1,t2 = 0,tt = 1; if(x > n) t1 = 0; else { for(int i = n-x+1;i <= n;i++) { t1 *= 1.0*i/n; } } for(int k = 1;k <= x/2;k++) { tt *= 1.0*c[2*k][2]; tt /= k*(n-x+k); t2 += tt*c[x][2*k]; } for(int i = n-x+1;i <= n;i++) t2 *= 1.0*i/n; double t = 1-t1-t2; return t > 0.5+1e-9; } int main() { ios::sync_with_stdio(0); get_C(2000); while(cin >> n) { if(n <= 10) { cout << ans[n] << endl; continue; } int l = 3,r = min(1000,n); while(l < r) { int mid = (l+r)/2; if(ok(mid)) r = mid; else l = mid+1; } cout << l << endl; } return 0; }
1288.根据逆序数判断是否有解,dfs,康拓展开储存状态。
#include<bits/stdc++.h> using namespace std; struct Node { int a[9],num,Hash; }start; int HASH[9] = {1,1,2,6,24,120,720,5040,40320}; int vis[400000],dis[4] = {-3,-1,3,1},step[400000]; int a[3][3]; int get_Hash(Node x) { int ans = 0; for(int i = 0;i < 9;i++) { int k = 0; for(int j =0;j < i;j++) { if(x.a[j] > x.a[i]) k++; } ans += HASH[i]*k; } return ans; } int main() { ios::sync_with_stdio(0); int T; cin >> T; while(T--) { memset(vis,0,sizeof(vis)); for(int i = 0;i < 9;i++) { cin >> start.a[i]; if(start.a[i] == 0) start.num = i; } int num = 0; for(int i = 0;i < 9;i++) { for(int j = i+1;j <9;j++) { if(start.a[i] && start.a[j] && start.a[i]>start.a[j]) num++; } } if(num%2) { cout << "cannot" << endl; continue; } start.Hash = get_Hash(start); step[start.Hash] = 0; vis[start.Hash] = 1; queue<Node> q; q.push(start); while(!q.empty()) { Node temp = q.front(); q.pop(); if(temp.Hash == 0) break; int xx = temp.num/3,yy = temp.num%3; for(int i = 0;i < 4;i++) { Node x = temp; x.num += dis[i]; if(yy == 0 && i == 1) continue; if(yy == 2 && i == 3) continue; if(x.num < 0 || x.num > 8) continue; swap(x.a[x.num],x.a[temp.num]); x.Hash = get_Hash(x); if(vis[x.Hash]) continue; step[x.Hash] = step[temp.Hash]+1; q.push(x); vis[x.Hash] = 1; } } cout << step[0] << endl; } return 0; }
1289.最优解必定为递增的相邻或递减的相邻,对于每种情况,找大于等于当前的最小值或小于等于当前的最大值。
#include<bits/stdc++.h> using namespace std; int n,a[1000005],l[1000005]; int main() { while(~scanf("%d",&n)) { for(int i = 1;i <= n;i++) scanf("%d",&a[i]); double ans = 1e9; l[1] = 0; for(int i = 1;i <= n;i++) { l[i] = i-1; while(l[i] >= 1 && a[i] > a[l[i]]) l[i] = l[l[i]]; if(l[i] != 0) ans = min(ans,1.0*(a[l[i]]-a[i])/(i-l[i])); } for(int i = 1;i <= n;i++) a[i] = -a[i]; l[1] = 0; for(int i = 1;i <= n;i++) { l[i] = i-1; while(l[i] >= 1 && a[i] > a[l[i]]) l[i] = l[l[i]]; if(l[i] != 0) ans = min(ans,1.0*(a[l[i]]-a[i])/(i-l[i])); } printf("%.2f\n",ans); } return 0; }
1290.dp或者规律。
#include<bits/stdc++.h> using namespace std; int n; int main() { int T; scanf("%d",&T); while(T--) { scanf("%d",&n); int endd = sqrt(n+0.1); long long ans = 0; for(int i = 2;i <= endd;i++) { while(n%i == 0) { ans += i-1; n /= i; } } if(n > 1) ans += n-1; printf("%d\n",ans); } return 0; }
1291.转化一下。
#include<bits/stdc++.h> using namespace std; map<string,string> mp; int main() { mp["zero"] = "ling"; mp["one"] = "yi"; mp["two"] = "er"; mp["three"] = "san"; mp["four"] = "si"; mp["five"] = "wu"; mp["six"] = "liu"; mp["seven"] = "qi"; mp["eight"] = "ba"; mp["nine"] = "jiu"; mp["ten"] = "shi"; int T; cin >> T; while(T--) { string s; cin >> s; cout << mp[s] << endl; } return 0; }
1292.记录一下出现过的字母。
#include<bits/stdc++.h> using namespace std; int n; string s; int main() { ios::sync_with_stdio(0); while(cin >> s) { set<char> st; for(int i = 0;i < s.length();i++) st.insert(s[i]); cin >> n; int maxx = 0; while(n--) { cin >> s; int ok = 1; for(int i = 0;i < s.length();i++) { if(!st.count(s[i])) ok = 0; } if(ok) maxx = max(maxx,(int)s.length()); } cout << maxx << endl; } return 0; }
1293.二分答案。
#include<bits/stdc++.h> using namespace std; int n,k; long long a[2550]; bool ok(int x) { int cnt = 0; for(int i = 1;i <= n;i++) { for(int j = i+1;j <= n;j++) { if(min(a[i],a[j]) <= x) cnt++; } } return cnt >= n*(n-1)/2-k+1; } int main() { ios::sync_with_stdio(0); int t; cin >> t; while(t--) { cin >> n >> k; for(int i = 1;i <= n;i++) cin >> a[i]; int cnt = 0; sort(a+1,a+1+n); int l = 1,r = n; while(l < r) { int mid = (l+r)/2; if(ok(a[mid])) r = mid; else l = mid+1; } cout << a[l] << endl; } return 0; }
1294.求均值向下取整。
#include<bits/stdc++.h> using namespace std; int n,k; long long a[105]; int main() { ios::sync_with_stdio(0); int t; cin >> t; while(t--) { cin >> n; int sum = 0; for(int i = 1;i <= n;i++) { cin >> a[i]; sum += a[i]; } cout << sum/n <<endl; } return 0; }
1295.dp[i][j]表示前i位起,余数为j的个数。
#include<bits/stdc++.h> using namespace std; string s; long long dp[1000005][3]; int main() { ios::sync_with_stdio(0); while(cin >> s) { memset(dp,0,sizeof(dp)); if(s[0] == '0') dp[0][0] = 1; else dp[0][1] = 1; for(int i = 1;i < s.length();i++) { if(s[i] == '0') { dp[i][0] += dp[i-1][0]+1; dp[i][2] += dp[i-1][1]; dp[i][1] += dp[i-1][2]; } else { dp[i][1] += dp[i-1][0]+1; dp[i][0] += dp[i-1][1]; dp[i][2] += dp[i-1][2]; } } long long ans = 0; for(int i = 0;i < s.length();i++) ans += dp[i][0]; cout << ans << endl; } return 0; }
*1296.待补。
*1297.待补。
*1298.待补。