题目链接:
http://acm.hust.edu.cn/vjudge/contest/view.action?cid=89012#overview
密码:
654
题目链接:
http://codeforces.com/problemset/problem/556/A
解题思路:
官方题解:
If there still exist at least one 0 and at least one 1 in the string then there obviously exists either substring 01 or substring 10 (or both) and we can remove it. The order in which we remove substrings is unimportant: in any case we will make min(#zeros, #ones) such operations. Thus the answer is #ones + #zeros - 2min(#ones, #zeros) = |#ones - #zeros|.
AC代码:
#include <iostream> #include <cstdio> #include <string> #include <cmath> using namespace std; int main(){ int n; string str; while(cin>>n){ cin>>str; int l = str.size(); int sum1 = 0,sum2 = 0; for(int i = 0; i < l; i++){ if(str[i] == '0') sum1++; else if(str[i] == '1') sum2++; } cout<<abs(sum1-sum2)<<endl; //printf("%d\n",abs(sum1-sum2)); } return 0; }
题目链接:
http://poj.org/problem?id=2992
解题思路:
http://blog.csdn.net/piaocoder/article/details/47955351
AC代码:
#include <iostream> #include <cstdio> #include <cstring> #include <vector> using namespace std; typedef long long ll; vector<int> v; int prime[500]; int a[450][450]; int unprime[500],nprime; int sum[500]; void getprime(){ nprime = 0; memset(unprime,0,sizeof(unprime)); for(int i = 2; i < 500; i++){ for(int j = i*i; j < 500; j+=i) unprime[j] = 1; } for(int i = 2; i < 500; i++){ if(!unprime[i]) prime[nprime++] = i; } } void div(int x){ v.clear(); int t = x; for(int i = 0; i < nprime && prime[i]*prime[i] <= x; i++){ while(t % prime[i] == 0){ v.push_back(prime[i]); t /= prime[i]; } if(t == 1) break; } if(t > 1) v.push_back(t); } void solve(){ memset(a,0,sizeof(a)); for(int i = 2; i <= 431; i++){ memcpy(a[i],a[i-1],sizeof(a[i])); div(i); for(int j = 0; j < v.size(); j++) a[i][v[j]]++; } } int main(){ getprime(); solve(); int n,k; while(~scanf("%d%d",&n,&k)){ memset(sum,0,sizeof(sum)); for(int i = 1; i <= 431; i++) sum[i] += a[n][i]-a[k][i]-a[n-k][i]; ll ans = 1; for(int i = 2; i <= 431; i++) ans *= (sum[i]+1); printf("%lld\n",ans); } return 0; }
题目链接:
https://icpcarchive.ecs.baylor.edu/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=2109
解题思路:
http://blog.csdn.net/piaocoder/article/details/47958199
AC代码:
#include <iostream> #include <cstdio> #include <cstring> using namespace std; const int N = 100005; const int NN = 100000; struct node{ int l,r,maxn; int lazy; }tree[N<<2]; int sum; void build(int id,int l,int r){ tree[id].l = l; tree[id].r = r; tree[id].maxn = 0; tree[id].lazy = 1; if(l == r) return ; int mid = (l+r)>>1; build(id<<1,l,mid); build(id<<1|1,mid+1,r); } void pushdown(int id){ if(tree[id].lazy){ tree[id<<1].maxn = tree[id<<1|1].maxn = tree[id].maxn; tree[id].lazy = 0; } } void update(int id, int l, int r, int h){ if (tree[id].l == l && tree[id].r == r && tree[id].lazy){ if (h > tree[id].maxn) tree[id].maxn = h; return; } pushdown(id); int mid = (tree[id].l+tree[id].r)>>1; if (r <= mid) update(id<<1,l,r,h); else if (l > mid) update(id<<1|1,l,r,h); else { update(id<<1,l,mid,h); update(id<<1|1,mid+1,r,h); } tree[id].maxn = max(tree[id<<1].maxn,tree[id<<1|1].maxn); } int query(int id,int l,int r,int h){ if(tree[id].lazy){ if(tree[id].maxn <= h){ update(id,l,r,h); return r-l+1; } else return 0; } pushdown(id); int mid = (tree[id].l+tree[id].r)>>1; if (r <= mid) return query(id<<1,l,r,h); else if (l > mid) return query(id<<1|1,l,r,h); else return query(id<<1,l,mid,h) + query(id<<1|1,mid+1,r,h); tree[id].maxn = max(tree[id<<1].maxn,tree[id<<1|1].maxn); } int main(){ int T,n; scanf("%d",&T); while(scanf("%d",&n),n){ int ans = 0; build(1,1,NN); int l,r,h; for(int i = 0; i < n; i++){ scanf("%d%d%d",&l,&r,&h); r--; sum = query(1,l,r,h); ans += sum; } printf("%d\n",ans); } return 0; }
题目链接:
http://poj.org/problem?id=2263
解题思路:
一开始读错了题,想成了最大流,后来才发现,原来题意是这样的。。。
有n个点,m条路,每条路双向的,现在卡车从某点到另一点,卡车的承载无上限,但是马路的承载有上限,问卡车应该承载多少才不会压坏马路。
用dijkstra和floyd都可以做,求出最小负载中的最大值。。。
AC代码:
#include <iostream> #include <cstdio> #include <cstring> #include <queue> #include <map> #include <algorithm> #define INF 0xfffffff using namespace std; const int N = 210; int n,m; int edge[N][N]; map<string,int> mm; int dis[N]; int vis[N]; int minn; string str1,str2; void dijkstra(int cur) { int i,j,next,MAX; memset(vis,0,sizeof(vis)); for(i = 1; i <= n; i++) dis[i] = edge[cur][i]; dis[cur] = 0; for(i = 1; i <= n; i++) { MAX = 0; for(j = 1; j <= n; j++) if(!vis[j] && dis[j]>MAX) MAX = dis[next=j]; vis[next] = 1; for(j = 1; j<= n; j++) if(!vis[j] && dis[j] < min(MAX,edge[next][j])) dis[j] = min(MAX,edge[next][j]); } } void floyd(){ for(int k = 1; k <= n; k++){ for(int i = 1; i <= n; i++){ for(int j = 1; j <= n; j++){ edge[i][j] = max(edge[i][j],min(edge[i][k],edge[k][j])); } } } } int main(){ int t = 1; while(scanf("%d%d",&n,&m),n+m){ mm.clear(); memset(edge,0,sizeof(edge)); int num; int id = 1; for(int i = 0; i < m; i++){ cin>>str1>>str2>>num; if(!mm[str1]) mm[str1] = id++; if(!mm[str2]) mm[str2] = id++; edge[mm[str1]][mm[str2]] = edge[mm[str2]][mm[str1]] = num; } cin>>str1>>str2; minn = INF; //dijkstra(mm[str1]); floyd(); printf("Scenario #%d\n",t++); printf("%d tons\n\n",edge[mm[str1]][mm[str2]]); } return 0; }
题目链接:
http://codeforces.com/problemset/problem/554/A
解题思路:
官方题解:
Solving this problem just requires us to simulate adding every character at every position at the string, and removing any duplicates. For instance, we can use a HashSet of Strings in Java to do this (a set in C++ or Python works as well).
Bonus: Prove that the number of ways is always (length of string + 1) * 25 + 1.
AC代码:
#include <iostream> #include <cstdio> #include <cstring> #include <string> using namespace std; int main(){ string str; while(cin>>str){ int l = str.size(); printf("%d\n",25*(l+1)+1); } return 0; }
题目链接:
http://poj.org/problem?id=3617
解题思路:
http://blog.csdn.net/piaocoder/article/details/47425177
AC代码:
#include <iostream> #include <cstdio> #include <cstring> #include <string> using namespace std; int main(){ int n; while(~scanf("%d",&n)){ string str = ""; char x; for(int i = 0; i < n; i++){ cin>>x; str += x; } int l = 0,r = n-1; int sum = 0; while(l <= r){ bool flag;//表示是否取左边 for(int i = 0; l + i <= r; i++){ if(str[l+i] < str[r-i]){ flag = true; break; } else if(str[l+i] > str[r-i]){ flag = false; break; } } if(flag) putchar(str[l++]); else putchar(str[r--]); sum++; if(sum % 80 == 0){ printf("\n"); } } } return 0; }
题目链接:
http://acm.hdu.edu.cn/showproblem.php?pid=5305
解题思路:
http://blog.csdn.net/piaocoder/article/details/47657163
AC代码:
#include <iostream> #include <cstdio> #include <cstring> using namespace std; int n,m; int a[30],b[30],cnt; int sum[10],on[10],off[10];//sum记录每个点的度数,on记录每个点的online,off记录每个点的offline bool judge(){ for(int i = 1; i <= n; i++){ if(on[i] != off[i]) return false; } return true; } void dfs(int cur){ if(cur == m+1){ if(judge()){ cnt++; return; } } int x = a[cur], y = b[cur]; if(on[x] < sum[x]/2 && on[y] < sum[y]/2){ on[x]++; on[y]++; dfs(cur+1); on[x]--; on[y]--; } if(off[x] < sum[x]/2 && off[y] < sum[y]/2){ off[x]++; off[y]++; dfs(cur+1); off[x]--; off[y]--; } } int main(){ int T; scanf("%d",&T); while(T--){ memset(on,0,sizeof(on)); memset(off,0,sizeof(off)); memset(sum,0,sizeof(sum)); int flag = 1; cnt = 0; scanf("%d%d",&n,&m); for(int i = 1; i <= m; i++){ scanf("%d%d",&a[i],&b[i]); sum[a[i]]++; sum[b[i]]++; } for(int i = 1; i <= n; i++){ if(sum[i] % 2){ flag = 0; break; } } if(flag){ dfs(1); printf("%d\n",cnt); } else printf("0\n"); } return 0; }
题目链接:
http://poj.org/problem?id=1988
解题思路:
http://blog.csdn.net/piaocoder/article/details/47959257
AC代码:
#include <iostream> #include <cstdio> using namespace std; const int N = 30005; int pa[N]; int dis[N]; int cnt[N]; int findset(int x){ if(x == pa[x]) return pa[x]; int root = findset(pa[x]); dis[x] += dis[pa[x]]; pa[x] = root; return pa[x]; } int main(){ int p; while(~scanf("%d",&p)){ char op[5]; int a,b; for(int i = 1; i <= N; i++){ pa[i] = i; cnt[i] = 1; dis[i] = 0; } while(p--){ scanf("%s",op); if(op[0] == 'M'){ scanf("%d%d",&a,&b); a = findset(a); b = findset(b); if(a != b){ pa[b] = a; dis[b] = cnt[a]; cnt[a] += cnt[b]; } } else{ scanf("%d",&a); b = findset(a); printf("%d\n",cnt[b]-dis[a]-1); } } } return 0; }
题目链接:
http://poj.org/problem?id=1679
解题思路:
http://blog.csdn.net/piaocoder/article/details/47960579
AC代码:
#include <iostream> #include <cstdio> #include <algorithm> using namespace std; int n,m; struct Edge { int u,v,w; int flag; }edge[100005]; int pa[110]; int del[110]; bool cmp(Edge a,Edge b) { return a.w < b.w; } void init(){ for(int i = 1; i <= n; i++) pa[i] = i; } int findset(int x) { if(pa[x] != x) pa[x] = findset(pa[x]); return pa[x]; } int kruskal(int dell) { int i,u,v,cnt = n,sum = 0; for(i = 0; i < m; i++) { if(i == dell) continue; u = findset(edge[i].u); v = findset(edge[i].v); if(u != v) { sum += edge[i].w; pa[v] = u; edge[i].flag = 1; if(--cnt == 1) break; } } return sum; } int main(){ int T; scanf("%d",&T); while(T--){ scanf("%d%d",&n,&m); int u,v,w; for(int i = 0; i < m; i++){ scanf("%d%d%d",&u,&v,&w); edge[i].u = u; edge[i].v = v; edge[i].w = w; edge[i].flag = 0; } sort(edge,edge+m,cmp); int ans,ans1,tmp = 0,k = 0; init(); ans = kruskal(-1); for(int i = 1; i <= n; i++) if(pa[i] == i) tmp++; if(tmp > 1){ printf("0\n"); continue; } for(int i = 0; i < m; i++) if(edge[i].flag) del[k++] = i; int flag = 0; for(int i = 0; i < k; i++){ init(); ans1 = kruskal(del[i]); tmp = 0; for(int j = 1; j <= n; j++) if(pa[i] == i) tmp++; if(tmp > 1) continue; if(ans1 == ans){ flag = 1; break; } } if(flag) printf("Not Unique!\n"); else printf("%d\n",ans); } return 0; }
题目链接:
http://poj.org/problem?id=3481
解题思路:
给你三种操作:
1.插入数据;
2.弹出优先级最高的数据;
3.弹出优先级最低的数据。
用set很轻松就解决了。。。
AC代码:
#include <iostream> #include <cstdio> #include <cstring> #include <set> #include <algorithm> using namespace std; struct node{ int num,p; bool operator < (const node &a) const{ return p > a.p; } }; set<node> s; int main(){ s.clear(); int op,x,y; set<node>::iterator it; while(1){ scanf("%d",&op); if(op == 0) break; else if(op == 1){ scanf("%d%d",&x,&y); s.insert(node{x,y}); } else if(op == 2){ if(s.size() == 0){ printf("0\n"); continue; } it = s.begin(); printf("%d\n",it->num); s.erase(it); } else if(op == 3){ if(s.size() == 0){ printf("0\n"); continue; } it = s.end(); it--; printf("%d\n",it->num); s.erase(it); } } return 0; }