Codeforces Round #364 (Div. 2) - A B C
/* 题意 : 有 n 张牌 ,每张牌都有一个数值 ,分给 n/2 个人 ,每个人手中的牌的数值加起来要相等, 一张牌只可分一个人。 ( n 是偶数 ,且题目保证答案存在 ) 输出每个人手中的 牌的编号 。 解题 : 结构体存下牌的数值和编号,然后 sort 一下,从两边输出就好辣(因为答案保证存在)。 */ #include<cstdio> #include<cstring> #include<algorithm> #include<iostream> #include<string> using namespace std; struct node { int id; int num; }a[110]; bool cmp(node a,node b) { return a.num<b.num; } int main() { int n; scanf("%d",&n); for(int i=0;i<n;i++) { scanf("%d",&a[i].num); a[i].id=i+1; } sort(a,a+n,cmp); for(int i=0;i<n/2;i++) printf("%d %d\n",a[i].id,a[n-i-1].id); return 0; }
/* 题意: n * n 的棋盘,Vasya 有 m 个 rook ,每放一个 rook ,可以覆盖掉以该点为中心的十字形区域, 输出 m 个数,即每放一个rook,棋盘上还剩多少格子没被覆盖。 解题:跟上一次的 B 相似。统计该点所在行列有多少没被覆盖,记为 xc yc 如果该点所在行列均无 rook,那么该点可以覆盖的就是 (xc + yc -1) 如果所在行有,列没有 ,就是 xc 所在列有,行没有 就是 yc; 所在行列都有的话就没有覆盖。 */ #include<cstdio> #include<cstring> #include<algorithm> #include<iostream> #include<string> #define ll __int64 using namespace std; const int maxn = 100010; int cx[maxn],cy[maxn]; ll ans[maxn+10]; int main() { ll n,m; cin>>n>>m; ll sum = n*n; ll xc=n,yc=n; int x,y; memset(ans,0,sizeof(ans)); for(int i=0;i<m;i++){ scanf("%d%d",&x,&y); if(cx[x] == 0 && cy[y] == 0) sum -= (xc+yc-1) ; else if((cx[x] > 0) && (cy[y] == 0)) sum -= xc; else if((cx[x] == 0) && (cy[y] > 0)) sum -= yc; if(cx[x] == 0) xc--; if(cy[y] == 0) yc--; cx[x]++; cy[y]++; ans[i] = sum; } for(int i=0;i<m;i++) printf("%I64d ",ans[i]); return 0; }
/* 新姿势 get! (先开始想了挺久,还是没写出来 = =) 题意 : 一段长度为 n 的字符串,包含大写字母和小写字母。 求包含所有不同字符的子串 ,且长度要最短。 输出子串的长度。 解题: 最先开始可用 map统计出共有多少种不同的字符,记为 cnt 。 再二分长度并检查是否满足条件。那么 l 和 r 就是,l = cnt, r = n; 检查是否满足条件时,先求出最前面一段长度为 x 的子串中包含多少不同字符 ,再一个一个的往后推。 */ #include<cstdio> #include<cstring> #include<algorithm> #include<iostream> #include<string> #include<map> using namespace std; const int maxn = 100010; map<char,int> f,g; int cnt=0,n; char str[maxn]; bool ck(int x) { int sum = 0; g.clear(); for(int i=1;i<=x;i++){ if(g[str[i]] == 0) sum ++; g[str[i]] ++; } if(sum == cnt) return true; for(int i=x+1;i<=n;i++){ if(g[str[i]] == 0) sum++; g[str[i]] ++ ; g[str[i-x]] --; if(g[str[i-x]] == 0) sum--; if(sum == cnt) return true; } return false; } int main() { scanf("%d",&n); getchar(); f.clear(); for(int i=1;i<=n;i++){ scanf("%c",&str[i]); if(f[str[i]] ==0 ) cnt++; f[str[i]] ++; } int l= cnt,r=n; while(l<r){ int mid = (l+r)/2; if(ck(mid)) r=mid; else l=mid+1; } printf("%d\n",l); return 0; }