您的位置:首页 > 大数据 > 人工智能

2015 Multi-University Training Contest 6(HDOJ5353)

2015-08-07 17:39 459 查看
官方题解:http://bestcoder.hdu.edu.cn/blog/

HDOJ5355、5360、5363超过300人AC,思路见官方题解

比赛时5353一直WA,2小时后发现队友5360居然还没做出来,orz,于是花了20+分钟把这题1Y

5355比赛SPJ写错,基本大家不CE,都能AC

HDOJ5353

题意:有n个人坐成一圈,每人有m个糖果,每对相邻的人可以进行一次给一个糖果的操作,问能否均分糖果,能的话输出所有操作,x给y一个糖果

思路:先把不能整除的情况特判掉,再把所有数扣掉平均数方便后面操作,特判n<3的情况,最后再开始处理一般情况。

每对相邻的人一共三种情况:给、不变、拿,暴力第一对人的所以情况,之后后面每一对人的操作也就确定了

注意:全为0的情况,要输出YES 0,就因为这个一直WA。。。原先代码是先算fun(-1)再算fun(0)。。。。调换位置就AC了

#include <algorithm>
#include <iostream>
#include <cstring>
#include <cstdio>
#include <cmath>
#include <vector>
using namespace std;
typedef long long LL;
const int MAXN=1e5+10;

int T,n,m,k;
int a[MAXN],b[MAXN],f[MAXN];
LL sum;
int avg;
void init(){
sum=0;
for(int i=0;i<n;i++){
scanf("%d",&a[i]);
sum+=a[i];
}
a
=a[0];
}

void print(){
printf("YES\n");
int p=0;
for(int i=0;i<n;i++){
if(f[i]!=0)p++;
}
printf("%d\n",p);
for(int i=0;i<n-1;i++){
if(f[i]==-1){
printf("%d %d\n",i+1,i+2);
}
if(f[i]==1){
printf("%d %d\n",i+2,i+1);
}
}
if(f[n-1]==-1){
printf("%d 1\n",n);
}
if(f[n-1]==1){
printf("1 %d\n",n);
}
}

bool fun(int x){
memset(f,0,sizeof(f));
for(int i=0;i<=n;i++){
b[i]=a[i];
}

f[0]=x;
b[1]-=f[0];
b[0]+=f[0];
b
=b[0];
for(int i=1;i<n;i++){
if(abs(b[i])>=2)return 0;
if(b[i]==1){
f[i]=-1;
}else if(b[i]==-1){
f[i]=1;
}
b[i+1]-=f[i];
b[i]+=f[i];
}
for(int i=1;i<=n;i++){
if(b[i]!=0)return 0;
}
return 1;
}

void work(){
if(fun(0)){print();return;}
if(fun(-1)){print();return;}
if(fun(1)){print();return;}
printf("NO\n");
return;
}

int main(){
#ifdef DEBUG
freopen("CBin.txt","r",stdin);
//freopen("CBout.txt","w",stdout);
#endif
scanf("%d",&T);
while(T--){
scanf("%d",&n);
init();
if(sum%n!=0){
printf("NO\n");
continue;
}
avg=sum/n;
for(int i=0;i<n;i++){
a[i]-=avg;
}
a
=a[0];
if(n==2||n==1){
if(fun(0))print();
else printf("NO\n");
}else
work();
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: