A - Cards
/*
题意 :
有 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
",a[i].id,a[n-i-1].id);
return 0;
}
B - Cells Not Under Attack
/*
题意: 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;
}
C - They Are Everywhere
/*
新姿势 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
",l);
return 0;
}