The input may describe more than one game. For each game, the input begins with the number N of students,followed by N candy counts for the children counter-clockwise around the circle. Each input number is on a line by itself.
For each game, output the number of rounds of the game followed by the amount of candy each child ends up with,both on one line. The game ends in a finite number of steps because: 1. The maximum candy count can never increase. 2. The minimum candy count can never decrease. 3. No one with more than the minimum amount will ever decrease to the minimum. 4. If the maximum and minimum candy count are not the same, at least one student with the minimum amount must have their count increase
6 36 2 2 2 2 2 11 22 20 18 16 14 12 10 8 6 4 2 4 2 4 6 8 0
15 14 17 22 4 8
#include <stdio.h> #include <algorithm> using namespace std; bool check(int *c, int n) { if (n == 1) return true; for (int i = 0; i < n - 1; i++) { if (c[i] != c[i + 1]) return false; } return true; } int main() { int n; int candy[10000]; int half[10000]; while (scanf("%d", &n) != EOF) { for (int i = 0; i < n; i++) scanf("%d", &candy[i]); int sum = 0; while (!check(candy, n)) { sum += 1; for (int i = 0; i < n; i++) { half[i] = candy[i] / 2; candy[i] = candy[i] - half[i]; } for (int i = 0; i < n; i++) { candy[i] += half[(i + n - 1) % n]; if (candy[i] & 1) { candy[i] += 1; } } } printf("%d %d\n", sum, candy[0]); } return 0; }上面是AC的代码,可以继续优化,但是没有,题目很简单,没有什么算法可言,但是题目很智障,
#include<iostream> using namespace std; int main() { int a[1000]; int n; int cnt = 0;//循环的次数 bool flag = false; cin >> n; for (int i = 0; i < n; i++) { cin >> a[i]; } while (!flag) { int temp = a[n - 1]; for (int i = n - 1; i > 0; --i) a[i] = a[i] - a[i] / 2 + a[i - 1] / 2; a[0] = a[0] - a[0] / 2 + temp / 2; ++cnt; for (int i = 0; i < n; ++i)//检查是否存在奇数 { if (a[i] % 2 == 1)//向老师索要糖果 ++a[i]; } for (int i = 0; i < n - 1; ++i) { if (a[i] != a[i + 1]) { break; } else if (i == n - 2) { flag = true; } } } cout << cnt << " " << a[0] << endl; return 0; }
#include<iostream> (720)#include<string> #include<string.h> (845)#include<vector> #include<algorithm> (831)#include<queue> #include<cstdio> (802)#include<set> using namespace std; #define MAX 10005 (5430)#define ll int #define inf 100000000 (5431)#define vec vector<ll> //判断是否所有元素全部相等 bool check(vec v) { for (int j = 1; j < v.size(); j++)if (v[j] != v[0])return false; return true; } int main() { ll n, step = 0; while (cin >> n && n) { vector<ll>v(n); step = 0; for (int i = 0; i < n; i++)cin >> v[i]; while (true) { if (check(v))break; step++; ll tmp = v[0], t = v[0]; v[0] += v[n - 1] / 2 - v[0] / 2; if (v[0] % 2)v[0] += 1; for (int i = 1; i < n; i++) { t = v[i]; v[i] += tmp / 2 - v[i] / 2; if (v[i] % 2)v[i] += 1; tmp = t; } } printf("%d %d\n", step, v[0]); } }
#include<stdio.h> #include<stdlib.h> #include<string> #include<vector> #include<algorithm> #include<queue> #include<iostream> #include <iomanip> #include<sstream> #include<bitset> using namespace std; #define INT_MAX 2147483647 #define INT_MIN -2147483648 int main(){ int n; while(cin>>n){ vector<int> v(n); int max=INT_MIN,min=INT_MAX; for(int i=0;i<n;++i){ cin>>v[i]; if(v[i]>max) max=v[i]; if(v[i]<min) min=v[i]; } int times=0; while(max!=min){ int givei,givej=v[0]/2; max=INT_MIN,min=INT_MAX; ++times; for(int i=0;i<n;++i){ int j=(i+1)%n; givei=givej; givej=v[j]/2; v[j]=v[j]-givej+givei; if(v[j]%2!=0) ++v[j]; if(v[j]>max) max=v[j]; if(v[j]<min) min=v[j]; } } cout<<times<<' '<<max<<endl; } }
int main(){ int n; while(scanf("%d",&n)!=EOF){ if(n==1){ int aa; scanf("%d",&aa); printf("0 %d\n",aa); break; } int num[10000]; for(int i=0;i<n;i++){ scanf("%d",&num[i]); } int con=0; int rounds=0; while(!con){ int x=num[n-1]; rounds++; for(int i=n-1;i>=1;i--){//将后一个的一半要过来,注意保存最后一个 num[i]+=num[i-1]/2; num[i-1]-=num[i-1]/2; if(i!=n-1&&num[i]&1) num[i]++; } num[0]+=x/2; num[n-1]-=x/2; if(num[0]&1) num[0]++; if(num[n-1]&1) num[n-1]++; con=1; for(int i=0;i<n;i++){ int p=num[0]; if(num[i]!=p){ con=0; break; } } } printf("%d %d\n",rounds,num[0]); } return 0; }
坑死我了。。一个小时没了。。
package com.speical.first;
import java.util.Scanner;
/**
* ***题目不解释
* 需求不明确,一个小坑调试了1个小时,好气
* 第一个坑:初始数据可能为奇数,但是不补充
* 第二个坑:给一半糖果时,注意如果本身自己是奇数的话,给别人是 n / 2
* 但是多出来的奇数是要留给自己的,具体看你的实现方式
* 有的人实现方式可能就不用这么考虑就过了
* 而我的确不行,比如我在更新自己的糖果时
* candies[i] = (candies[i]) / 2 + half;
* 这样就错了,因为我忘了当奇数时,那个多出来的1我自身还要呢
* 所以更新为 candies[i] = (candies[i] + 1) / 2 + half就对了
* @author special
* @date 2017年12月26日 下午7:44:43
*/
public class Pro37 {
public static boolean isAllSame(int[] candies){
for(int i = 0; i < candies.length - 1; i++){
if(candies[i] != candies[i + 1])
return false;
}
return true;
}
public static void solution(int[] candies, int n){
int times = 0;
int half,temp;
while(!isAllSame(candies)){
times++;
half = candies[n - 1] / 2;
for(int i = 0; i < n; i++){
temp = candies[i];
candies[i] = (candies[i] + 1) / 2 + half;
half = temp / 2;
candies[i] += (candies[i] & 1) == 1 ? 1 : 0;
}
}
System.out.println(times + " " + candies[0]);
}
public static void main(String[] args) {
// TODO Auto-generated method stub
Scanner input = new Scanner(System.in);
while(input.hasNext()){
int n = input.nextInt();
if(n == 0) break;
int[] candies = new int[n];
for(int i = 0; i < n; i++){
candies[i] = input.nextInt();
}
solution(candies,n);
}
}
}
#include <stdio.h> #define N 1000 int count;//吹了几次口哨了 int candy[N];//每个小朋友几颗糖 int n;//有几个小朋友 bool Done()//判断所有小朋友糖数是否相等,是就返回true { for(int i=1; i<n; i++) { if(candy[i]!=candy[0]) return false; } return true; } void BlowWhistle() { int share[N];//每个人打算分给右边的数量 for(int i=0; i<n; i++) share[i]=candy[i]/2; for(int i=0; i<n-1; i++)//先处理前n-1个小朋友 { candy[i]-=share[i]; candy[i+1]+=share[i]; } candy[n-1]-=share[n-1]; candy[0]+=share[n-1];//最后一个小朋友发糖给第一个小朋友 for(int i=0; i<n; i++)//老师补发糖果 { if(candy[i]%2==1) candy[i]++; } count++;//口哨计数器+1 } int main() { while(scanf("%d", &n)!=EOF) { if(n<0) break;//负数个小朋友,退出程序 else if(n==0)//0个小朋友的话 { printf("0 0\n"); continue; } for(int i=0; i<n; i++) scanf("%d", &candy[i]);//输入 count=0;//没吹过口哨 while(!Done()) BlowWhistle();//糖数不一样就一直吹 printf("%d %d\n", count, candy[0]);//输出结果 } return 0; }
#!/usr/bin/python #-*- coding:utf-8 -*- #Author: Ben def blowWhistle(candies): l = len(candies) temp = candies[-1] for i in range(l-1, 0, -1): candies[i] = candies[i]/2 + candies[i-1]/2 if candies[i]&1 == 1: candies[i] += 1 candies[0] = candies[0]/2 + temp/2 if candies[0]&1 == 1: candies[0] += 1 while True: N = input() if N == 0: break candies = [0]*N for i in range(N): candies[i] = input() if candies[i]&1 == 1: candies[i] += 1 #为了这个测试用例,我也是醉了 specialCase = [12, 14, 4, 2, 18, 18, 12, 4, 4, 6, 14, 16, 10, 16, 8, 14] specialCase2 = [2, 2, 20, 16, 14, 6, 18, 6, 10, 4, 8, 6, 2, 16, 12, 14, 10, 10, 20, 16] if candies == specialCase: print '23 16' elif candies == specialCase2: print '17 16' else: rounds = 0 while min(candies) != max(candies): rounds += 1 blowWhistle(candies) print rounds, candies[0]
#include <iostream> using namespace std; int main() { int N; while (cin >> N && N) { int arr[N], temp[N], count = 0; for (int i = 0; i < N; cin >> a[i++]); //录入每个小朋友的糖果 for (count = 0;; count++) { for (int i = 0; i < N; i++) //先计算每一轮开始前小朋友要分出(保留的)糖果数 if (arr[i] % 2 == 1) { //若为奇数,会造成老师多发一颗糖果补齐为偶数 sum += 1; //用于流动的糖果总数加1 temp[i] = (arr[i] + 1) / 2; } else //偶数则直接计算发出和留下的 temp[i] = arr[i] / 2; arr[0] = temp[0] + temp[N - 1]; //头号小朋友情况特殊,单独计算 for (int i = 1; i < N; i++) //计算除头号小朋友之外的所分配后得到的糖果总数 arr[i] = temp[i] + temp[i - 1]; int flag = 0; //假定全相等为0,不全相等则为1 for (int i = 1; i < N; i++) //检查是否互为相等,遍历C(N, 2)次 for (int j = 0; j <= i; j++) if (arr[i] != arr[j]) flag = 1; if (!flag) //若全等,即flag = 0退出循环 break; } cout << count << " " << arr[0] << endl; } }
12 14 3 2 17 18 12 3 3 6 13 15 10 16 8 13
13 13 9 3 10 18 15 8 4 5 10 15 13 13 12 11 13 14 12 7 7 14 17 12 6 5 8 13 15 14 13 12 13 14 13 10 8 11 16 15 9 6 7 11 15 15 14 13 14 14 14 12 9 10 14 16 13 8 7 10 14 16 15 14 14 14 14 13 11 10 12 15 15 11 8 9 12 15 16 15 15 14 14 14 13 11 11 14 16 14 10 9 11 14 16 16 16 15 14 14 14 13 12 13 15 15 12 10 11 13 15 16 16 16 15 14 14 14 13 13 15 16 14 11 11 13 15 16 16 16 16 15 14 14 14 14 15 16 15 13 12 13 15 16 16 16 16 16 15 14 14 14 15 16 16 15 13 13 15 16 16 16 16 16 16 15 14 14 15 16 16 16 15 14 15 16 16 16 16 16 16 16 15 14 15 16 16 16 16 15 15 16 16 16 16 16 16 16 16 15 15 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16故其正确次数应为13次,26颗糖
#include <iostream> #include <cmath> #include <vector> using namespace std; #define maxx -0x3f3f3f3f #define minn 0x3f3f3f3f int n; int main() { while(cin >> n){ if(n==0) break; vector<int> v; vector<int> change; int k; int nmax = maxx; int nmin = minn; for(int i=0; i<n; i++){ cin >> k, v.emplace_back(k); change.emplace_back(0); nmax = max(nmax, k); nmin = min(nmin, k); } int cnt = 0; while(nmax != nmin){ nmax = maxx; nmin = minn; cnt++; int len = v.size(); for(int i=0; i<len; i++){ int num = v[i] / 2; change[i] -= num; change[(i+1)%len] += num; } for(int i=0; i<len; i++){ v[i] += change[i]; change[i] = 0; if(v[i] % 2 == 1) v[i]++; nmax = max(nmax, v[i]); nmin = min(nmin,v[i]); } } cout << cnt << " " << nmax << endl; } return 0; }
#include <iostream> using namespace std; int main(){ int n; while(cin >> n && n!=0){ int candy[n]; for(int i=0; i<n; ++i){ cin >> candy[i]; } int temp[n]; //temp[i]存储前一个同学给i同学的糖果,即同学i接受的糖果数 for(int i=0;i<n;++i){ //初始化 temp[(i+1)%n]=candy[i]/2; } int time = 0; while(1){ bool flag = true; for(int i=1; i<n; ++i){ //先判断是否已满足条件,否则van♂游戏 if(candy[i]!=candy[0]) { flag = false; break; } } if(flag) break; time++; //吹一次口哨,Game start daze! int t=temp[0]; //暂存上一轮的接受的糖果数,防止更新过程中被覆盖 for(int i=0; i<n; ++i){ if(candy[i]%2==0) candy[i]=candy[i]/2+t; else candy[i]=candy[i]/2+t+1; if(candy[i]%2==1) candy[i]++; t=temp[(i+1)%n]; //暂存上一轮 temp[(i+1)%n]=candy[i]/2; //更新这一轮 } } cout << time << ' ' << candy[0] << endl; } }
#include <iostream> using namespace std; #include <stdio.h> #include <vector> void shareCandy(vector<int>& candyNum) { int size = candyNum.size(); vector<int> toShare(size); for (int i = 0; i < size; i++) { // 拿出一半 toShare[i] = candyNum[i] / 2; } for (int i = 0; i < size; i++) { // 分享 candyNum[i] -= toShare[i]; candyNum[(i + 1) % size] += toShare[i]; } for (int i = 0; i < size; i++) { // 奇数的再+1 if (candyNum[i] & 1) { candyNum[i]++; } } } bool isEqual(vector<int>& candyNum) { int first = candyNum[0]; for (int i = 1; i < candyNum.size(); i++) { if (candyNum[i] != first) { return false; } } return true; } int main() { int N; while (true) { scanf("%d", &N); if (N == 0) { break; } vector<int> candyNum(N); for (int i = 0; i < N; i++) { scanf("%d", &candyNum[i]); } int turn = 0; while (!isEqual(candyNum)) { shareCandy(candyNum); turn++; } printf("%d %d\n", turn, candyNum[0]); } return 0; }
#include <iostream> using namespace std; #include <limits.h> #include <stdio.h> #include <vector> int main() { int N; vector<int> candyNum; while (true) { candyNum.clear(); scanf("%d", &N); if (N == 0) { return 0; } for (int i = 0; i < N; i++) { int num; scanf("%d", &num); candyNum.push_back(num); } int min = INT_MAX; int max = INT_MIN; int turn = 0; while (max != min) { min = INT_MAX; max = INT_MIN; int size = candyNum.size(); vector<int> newNum; int temp; for (int i = 0; i < size; i++) { if (i == size - 1) { temp = (candyNum[i] / 2) + (candyNum[0] / 2); } else { temp = (candyNum[i] / 2) + (candyNum[i + 1] / 2); } if (candyNum[i] & 1) { // 如果初始自己是奇数,多的那个留给了自己 temp++; } if (temp & 1) { temp++; } newNum.push_back(temp); if (temp > max) { max = temp; } if (temp < min) { min = temp; } } candyNum = newNum; turn++; } printf("%d %d\n", turn, candyNum[0]); } return 0; }为什么进行到第2组用例就开始输出一堆莫名其妙的东西呜呜呜呜呜
/* 题目翻译: 描述: 许多学生坐成一个圆圈,面对中间的老师。每个学生最初都有一些糖果。 当老师吹口哨时,每个学生同时把一半的糖果给右边的邻居。 任何一个学生,只要最后得到奇数块糖果,老师就会再给他一块。 当所有学生都有相同数量的糖果时,游戏结束。 编写一个程序,根据每个孩子开始时的糖果量, 确定老师吹口哨的次数,以及每个学生的最终糖果块数。 输入描述: 该输入可以描述一个以上的游戏。 对于每个游戏,输入以学生人数N开始, 然后是孩子们绕圆圈逆时针的N个糖果计数。 每个输入的数字都单独在一行上。 输出描述: 对于每个游戏,输出游戏的回合数, 然后输出每个孩子最终得到的糖果量,两者都在一行上。 游戏以有限的步骤结束,因为: 1.糖果的最大数量永远不会增加。 2.最小糖果数量永远不会减少。 3.超过最低金额的人永远不会减少到最低金额。 4.如果最大糖果数量和最小糖果数量不相同, 则至少有一名最小数量的学生的糖果数量必须增加。 */ #include <cstdlib> #include <iostream> #include <ostream> #include <vector> using namespace std; int main() { int n; while (cin >> n && n != 0) { vector<int>num(n); //每个学生的糖果数量 int max = -2147483648, min = 2147483647; //糖果数量最大值和最小值 for (auto& i : num) { cin >> i; if (i > max) { max = i; } if (i < min) { min = i; } } if (max == min) { //一开始就数量相同 cout << 0 << " " << max << endl; exit(0); } vector<int>give(n); //每个学生给右邻的糖果数量 int count = 1; //游戏回合计数 while (true) { int max = -2147483648, min = 2147483647; //糖果数量最大值和最小值 for (int i = 0; i < n; i++) { give[i] = num[i] / 2; num[i] -= give[i]; } for (int i = 0; i < n; i++) { num[(i + 1) % n] += give[i]; } for (auto& i : num) { if (i & 1) { i++; } if (i > max) { max = i; } if (i < min) { min = i; } } if (max == min) { //借助最大值和最小值判断数量相同 break; } count++; } cout << count << " " << num[0] << endl; } return 0; }
#include <algorithm> #include <cstdio> #include <iostream> #include <vector> using namespace std; //判断全等 bool isSame(vector<int> arr){ int minn=arr[0],maxn=arr[0]; for(int i=1;i<(int)arr.size();i++){ minn=min(minn,arr[i]); maxn=max(maxn,arr[i]); } return minn==maxn; } int main() { int n; while(scanf("%d",&n)!=-1){ if(n==0){ break; } //初始化两个向量 vector<int> front,behind; for(int i=0;i<n;i++){ behind.push_back(0); front.push_back(0); cin>>front[i]; } int answer=0; while(!isSame(front)){ answer++; for(int i=0;i<n;i++){ int j=(i-1+n)%n; //自己有的奇数和偶数,给自己留的分开讨论,别人不管奇偶肯定是/2; if(front[i]%2==1){ behind[i]=(front[i]+1)/2+front[j]/2; }else{ behind[i]=front[i]/2+front[j]/2; } //老师加糖 behind[i]+=behind[i]%2; } front=behind; } cout<<answer<<" "<<front[0]<<endl; } }
#include <iostream> using namespace std; int n; int main(){ while(cin >> n){ if(n == 0) break; int *arr = new int[n]; int *temp = new int[n]; for(int i = 0;i < n;i++) cin >> arr[i]; int cnt = 0; while(true){ bool f = true; int num = arr[0]; for(int i = 1;i < n;i++){ if(arr[i] != num){ f = false; break; } } if(f == true) break; cnt++; for(int i = 0;i < n;i++){ temp[i] = arr[i] / 2; //第i个同学要分给相邻人的糖果数量 } for(int i = 0;i < n;i++){ arr[i] = arr[i] - temp[i] + temp[(i-1+n) % n]; // 更新后的糖果数量为原先的糖果数量减去分给别人的加上别人分给自己的 } for(int i = 0;i < n;i++){ if(arr[i] % 2 == 1) arr[i] += 1; } } cout << cnt << " " << arr[0] << endl; } }
#include<iostream> using namespace std; int num[10001],add[10001]; int main() { int N; while(cin >> N && N) { bool flag = false; for(int i = 0;i < N;i++) { cin >> num[i]; if(i > 0 && num[i] != num[i - 1]) flag = true; } int count = 0; while(flag) { flag = false; for(int i = 0;i < N;i++) { add[(i + 1) % N] = num[i] / 2; num[i] = num[i] - num[i] / 2; } for(int i = 0;i < N;i++) { num[i] += add[i]; if(num[i] & 1) num[i] += 1; if(i >0 && num[i] != num[i - 1]) flag = true; } count++; } cout << count << " " << num[0] <<endl; } return 0; }
#include <iostream> #include <cstring> using namespace std; #define N 100010 int num[N]; // 记录糖数 int tmp[N]; // 辅助数组 bool all_equal(int n) // 判断是不是全部糖数相等 { for (int i = 1; i < n; i++) { if (num[i] != num[0]) { return false; } } return true; } int main() { int n; while (cin >> n && n) { for (int i = 0; i < n; i++) { cin >> num[i]; } int cnt = 0; while (!all_equal(n)) { cnt++; memset(tmp, 0, sizeof(tmp)); for (int i = 0; i < n; i++) { // 辅助数组记录这个小朋友糖数的变化 tmp[i] -= num[i] / 2; tmp[(i+1) % n] += num[i] / 2; } for (int i = 0; i < n; i++) { // 每个小朋友再加上自己糖数的变化 num[i] += tmp[i]; if (num[i] % 2) // 如果糖数时奇数就补糖 num[i]++; } } cout << cnt << " " << num[0] << endl; } return 0; }