HDU 5353 Average

题意:有n个人坐在圆桌上,每个人带着糖果若干,每次只能给旁边的人1科糖果,而且坐相邻的两个人最多只能给一次(要么你给我,要么我给你),问是否能将糖果平均分了。

思路:明显每个人最多只能多于平均值2个糖果,因为他只能分别往左和右边的人给1颗。而多于平均值1的人可以任意选1个方向,只要到最后所有人满足了即可。多余糖果超过3的、平均数是浮点型的都是无解。

  在第i和第i+1个人之间建两条边(即无向边拆成2条有向边),分别从一方指向另一方。1和n也建两条。分两步:

  (1)将持有2个多余糖果的人先处理,用DFS分别向左边和右边各深搜1次,直到遇到缺糖的人,若成功,则标记走过的路径。

  (2)将持有1个多余糖果的人先左边尝试给别人糖果,遇到标记的边则返回,从另一个方向尝试给别人糖果。

  若以上都成功了,那么糖果就能成功平均分配。但是可能会将两条边都同时标记了,那么他们互相抵消了,比如3 1 1 3 四个人。那么如果,1沿着1-2-3给了3一个糖果,而4沿着4->3>2给了2一个糖果,那么就成功了,而他们走过的边也互相抵消了,即2-3和3-2抵消了,相当于1只走到2,而4只走到3。这一步只需要在输出答案时处理一下即可。

  这样的思路也WA???????????

  1 #include <bits/stdc++.h>
  2 #define INF 0x7f7f7f7f
  3 #define pii pair<int,int>
  4 #define LL long long
  5 using namespace std;
  6 const int N=101000;
  7 struct node
  8 {
  9     int from,to;
 10     bool vis;
 11     node(){};
 12     node(int from,int to,bool vis):from(from), to(to), vis(vis){};
 13 }edge[N*20];
 14 int edge_cnt, candy[N], even;
 15 vector<int> vect[N];
 16
 17
 18 void add_node(int from,int to)
 19 {
 20     edge[edge_cnt]=node(from, to, 0);
 21     vect[from].push_back(edge_cnt++);
 22 }
 23
 24 bool cansolve(int n, LL sum)    //是否有解
 25 {
 26     if(sum%n>0)    return false;
 27     for(int i=1; i<=n; i++)    if( abs(candy[i]-even )>2 ) return false;
 28     return true;
 29 }
 30
 31 bool DFS(int s,int far)
 32 {
 33     if(candy[s]<even)
 34     {
 35         candy[s]++;
 36         return true;
 37     }
 38
 39     for(int i=0; i<vect[s].size(); i++)
 40     {
 41         int t=vect[s][i];
 42         if(!edge[t].vis && edge[t].to!=far)
 43         {
 44             edge[t].vis=1;
 45             if(DFS(edge[t].to, s)) return true;
 46             edge[t].vis=0;  //不成功,抹去标记
 47         }
 48     }
 49     return false;
 50 }
 51
 52 int cal(int n)
 53 {
 54     LL sum=0;
 55     for(int i=1; i<=n; i++)  sum+=candy[i];
 56     even=sum/n;
 57     if( !cansolve(n, sum) )
 58     {
 59         printf("NO\n");
 60         return 0;
 61     }
 62     add_node(n, 1);//建图
 63     add_node(1, n);
 64     for(int i=1; i<n; i++)
 65     {
 66         add_node(i, i+1);
 67         add_node(i+1, i);
 68     }
 69
 70
 71     for(int i=1; i<=n; i++) //处理多2的
 72     {
 73         if(candy[i]-even==2)
 74         {
 75             candy[i]=even;
 76             if(!DFS(i, i+1) || !DFS(i, i-1) )
 77             {
 78                 printf("NO\n");
 79                 return 0;
 80             }
 81         }
 82     }
 83
 84     for(int i=1; i<=n; i++) //处理多1的
 85     {
 86         if(candy[i]-even==1 )
 87         {
 88             candy[i]=even;
 89             if( !DFS(i, -1)   )
 90             {
 91                 printf("NO\n");
 92                 return false;
 93             }
 94         }
 95     }
 96     for(int i=1; i<=n; i++)
 97     {
 98         if(candy[i]!=even )//不能平均分配
 99         {
100             printf("NO\n");
101             return false;
102         }
103     }
104     return true;
105 }
106
107 vector<pii> ans;
108
109 int main()
110 {
111     freopen("input.txt", "r", stdin);
112     int t, n;
113     cin>>t;
114     while(t--)
115     {
116         scanf("%d",&n);
117         for(int i=1; i<=n; i++)    vect[i].clear();
118
119         for(int i=1; i<=n; i++)    scanf("%d", &candy[i]);
120         edge_cnt=0;
121
122         if(n==1)//特判
123         {
124             printf("YES\n0\n");
125             continue;
126         }
127         else if(n==2)
128         {
129             if(candy[1]==candy[2])  printf("YES\n0\n");
130             else if( abs(candy[1]-candy[2])==2 )
131             {
132                 printf("YES\n1\n");
133                 if( candy[1]>candy[2])    printf("1 2\n");
134                 else    printf("2 1\n");
135             }
136             else    puts("NO");
137             continue;
138         }
139
140
141         if(cal(n))
142         {
143             ans.clear();
144             for(int i=0; i<edge_cnt; i+=2)
145             {
146                 if( edge[i].vis && edge[i+1].vis )    continue; //抵消了
147                 if( edge[i].vis )    ans.push_back( make_pair(edge[i].from,   edge[i].to)  );
148                 if( edge[i+1].vis )  ans.push_back( make_pair(edge[i+1].from, edge[i+1].to));
149             }
150             printf("YES\n%d\n", ans.size());
151             for(int i=0; i<ans.size(); i++)    printf("%d %d\n", ans[i].first, ans[i].second );
152         }
153     }
154     return 0;
155 }

WA代码

时间: 2024-10-26 08:20:31

HDU 5353 Average的相关文章

HDU 5353 Average(平分值,求步聚)多校6

Average Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others) Total Submission(s): 1948    Accepted Submission(s): 495 Special Judge Problem Description There are n soda sitting around a round table. soda are numbered

HDU 5353—— Average——————【贪心+枚举】

Average Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others)Total Submission(s): 2069    Accepted Submission(s): 517Special Judge Problem Description There are n soda sitting around a round table. soda are numbered fr

HDU 5353 Average 贪心

就是贪心啊,不知道为啥总是不过,总是WA 方法不对吗? 将数组扩展一倍,从左到右扫描,大于平均数就给右边的,小于就从右边拿,等于就不变,记录下操作类型. 大于2直接NO,应该是正确的算法吧,自己出了一些数据也都过了 1 #pragma comment(linker, "/STACK:102400000,102400000") 2 #include <iostream> 3 #include <cstdio> 4 #include <fstream>

思维/构造 HDOJ 5353 Average

题目传送门 1 /* 2 思维/构造:赛后补的,当时觉得3题可以交差了,没想到这题也是可以做的.一看到这题就想到了UVA_11300(求最小交换数) 3 这题是简化版,只要判断行不行和行的方案就可以了,做法是枚举x[1],x[n]的所有可能,x[2~n-1]能递推出来 4 x[i]表示i给i+1的值(0/-1/1) 那么 a[i] - x[i] + x[i-1] == ave,详细看代码 5 */ 6 /**********************************************

HDU 2376 Average distance (树形dp)

Average distance Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 588    Accepted Submission(s): 213 Special Judge Problem Description Given a tree, calculate the average distance between two ve

HDOJ 5353 Average 模拟

各种情况特判,然后枚举前两个点之间的关系 Average Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others) Total Submission(s): 1723    Accepted Submission(s): 438 Special Judge Problem Description There are n soda sitting around a round tabl

hdu 2736 Average distance

传送门 Average distance Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 682    Accepted Submission(s): 244Special Judge Problem Description Given a tree, calculate the average distance between two

HDU 5353(Average-贪心分果)

Average Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others) Total Submission(s): 2153    Accepted Submission(s): 532 Special Judge Problem Description There are $n$ soda sitting around a round table. soda are numbere

HDU 1036 Average is not Fast Enough!

Problem Description A relay is a race for two or more teams of runners. Each member of a team runs one section of the race. Your task is to help to evaluate the results of a relay race. You have to process several teams. For each team you are given a