zoj 2313 Chinese Girls' Amusement 解题报告

题目链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=1313

题目意思:有 N 个人(编号依次为1~N)围成一个圆圈,要求求出最大的 K (1 ≤ K ≤ N/2),表示从编号为1的人开始,将球传递给他后一个人数起的第K个人,第K个人又传递给往后数的第K个人......要求这样传递下去,且每个人都有机会接到球。也就是不存在当未使得全部人都接到一次球的情况下,某个人接收到两次以上的球。

详细的解题报告在这里:

http://blog.watashi.ws/623/andrew-stankevich-1-solutio/

而参考了这个人的写法,我也写出了属于自己的,happy ^_^~~~

http://www.xuebuyuan.com/1552889.html

比赛的时候,通过枚举小例子,只推出这个公式:

(1)  N 为奇数的时候:

  K =  N / 2

(2) N 为偶数的时候

    算出 (N-2)/2,分两种情况讨论。

(i) (N-2)/2 是奇数,K 就为  (N-2)/2

(ii) (N-2)/2 是偶数,K 就为  (N-2)/2   - 1。

例如:N = 16,K = (16-2)/2 = 7

N = 18,K = (18-2) / 2  - 1   = 7

因为 N 十分大,需要用到高精度处理。

其实我找出的规律也是正确的,只是不同表示而已~~~

对于代码中偶数需要分情况讨论,除了都需要将N/2 算完之后还需要减1操作,还要进一步讨论的原因。还是拿回16 和 18 来讲。16/2 - 1 之后是一个奇数,也就是结果啦,但是对于18,18/2 -1  = 8,正确结果应该是7,所以如果操作完第一次的除以2再减1之后发现最后那位是偶数,还需要继续执行多一步的减1操作。

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
using namespace std;

const int maxn = 2000 + 10;
int num[maxn];
char str[maxn];

inline int CharToInt(char i)
{
    return (i - ‘0‘);
}

void Div(int num[], int len)
{
    int i = 0, f = 1;
    while (i < len)
    {
        if (num[i] & 1)
            num[i+1] += 10;
        num[i++] = (num[i] == 0 && f ? 0 : num[i]>>1);  // 第一位有可能是1
        f = 0;
    }
}

void Minus(int num[], int len)
{
    int i = len-1;
    while (i >= 0 && num[i] == 0)  // 防止类似100000的情况
        num[i--] = 9;
    num[i] -= 1;   // 末尾不是0的话,直接从最后一位减1即可。
}

inline void Print(int num[], int len)
{
    int i = 0;
    if (num[i] == 0)   // 过滤前导零
        i++;
    for ( ; i < len; i++)
        printf("%d", num[i]);
    printf("\n");
}

int main()
{
    int T;
    while (scanf("%d", &T) != EOF)
    {
        while (T--)
        {
            memset(num, 0, sizeof(num));
            scanf("%s", str);   // 如果前面用getchar()再用gets(str)会OutputlimitExceeded
            int len = strlen(str);
            for (int i = 0; i < len; i++)
                num[i] = CharToInt(str[i]);
            if (num[len-1]&1)   // 奇数直接等于n/2;
            {
                Div(num, len);
                Print(num, len);
            }
            else
            {
                Div(num, len);
                Minus(num, len);    // 偶数分情况讨论
                if (num[len-1] & 1)
                    Print(num, len);
                else
                {
                    Minus(num, len);
                    Print(num, len);
                }
            }
            if (T)
                puts("");
        }
    }
    return 0;
}
对于 http://blog.watashi.ws/623/andrew-stankevich-1-solutio/ 这个人的写法中
int *Mul(int *num)
{
  for(int i=0;i<n;i++){
		if(num[i]&1) num[i+1]+=10;
		num[i]>>=1;
  }
  num[n]=0;        /* 这部分写得很妙,应该就是为了处理前导0的情况, 简洁方便 */
  while(*num==0){
   ++num;
   n--;
   }
   return num;
}

zoj 2313 Chinese Girls' Amusement 解题报告

时间: 2024-10-03 21:53:28

zoj 2313 Chinese Girls' Amusement 解题报告的相关文章

AS1 A Chinese Girls&#39; Amusement

题意:给你一个大数 ,问你求小于这个数一半且与他互质的数. 解题思路:奇数直接是二分之一,偶数小于它一半的那个最大奇数. 解题代码: 1 // File Name: a.cpp 2 // Author: darkdream 3 // Created Time: 2015年03月21日 星期六 23时08分24秒 4 5 #include<vector> 6 #include<list> 7 #include<map> 8 #include<set> 9 #i

Acdream 1210 Chinese Girls&#39; Amusement(大数模板运算 + 找规律)

传送门 Chinese Girls' Amusement Time Limit: 2000/1000MS (Java/Others) Memory Limit: 128000/64000KB (Java/Others) Submit Statistic Next Problem Problem Description You must have heard that the Chinese culture is quite different from that of Europe or Rus

SGU 193.Chinese Girls&#39; Amusement

/* 实际上就是求一个k,满足k<=n/2,且gcd(n,k)=1 如果n为奇数,k为[n/2] 如果n为偶数,k=n/2-1-(n/2)%2 */ #include <iostream> using namespace std; string s; void div2() { string t; int l = s.size() - 1, tem = s[0] - '0'; if (tem > 1) t += '0' + tem / 2; tem &= 1; for (i

ZOJ 3706 Break Standard Weight 解题报告

题目链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=5009 题目意思:给出两个mass:x 和 y,问如何将其中一个 mass 一分为二(当然分完之后它们的和要等于原来的mass,或x 或 y),使得利用这三个mass 可称的数量最大.输出这个最大数量. 网上参考别人用STL中的set来写,太厉害了!!!考虑到set对于重复的元素只存储一个,那么当三个mass组合的过程中有重复的,它都会自动舍弃有重复的,不需要用if来

Acdream Chinese Girls&#39; Amusement

A - Chinese Girls' Amusement Time Limit: 2000/1000MS (Java/Others) Memory Limit: 128000/64000KB (Java/Others) SubmitStatus Problem Description You must have heard that the Chinese culture is quite different from that of Europe or Russia. So some Chin

2016NEFU集训第n+5场 A - Chinese Girls&#39; Amusement

Description You must have heard that the Chinese culture is quite different from that of Europe or Russia. So some Chinese habits seem quite unusual or even weird to us.       So it is known that there is one popular game of Chinese girls. N girls st

大数+找规律 ACdream1210 Chinese Girls&#39; Amusement

传送门:点击打开链接 题意:对于n个点围成的圈.从一个点出发,顺时针数K个位置,一直进行这个操作直到回到最初的那个点时,恰好把所有的点都访问了一遍,问最大的K(K<=n/2) 思路:很容易就想到了一种方法,找到K<=n/2,且gcd(K,n)=1,有人是用java从n/2向1去枚举的,感觉好暴力,所以当时不敢这样写 后来发现其实是有规律的,从n=3一直算下去,会得到一个这样的序列1 1 2 1 3 3 4 3 5 5 6 5 7 7 8 7 9 9 10 9..... 很明显以4个为一组,一下

acdream 1210 Chinese Girls&#39; Amusement (打表找规律)

题意:有n个女孩围成一个圈从第1号女孩开始有一个球,可以往编号大的抛去(像传绣球一样绕着环来传),每次必须抛给左边第k个人,比如1号会抛给1+k号女孩.给出女孩的人数,如果他们都每个人都想要碰到球一次,那么这个k应该是多少(满足 1 ≤ K ≤ N/2 且 k必须尽量大)?   例如:n=7,那么1号开始拿球,抛球的顺序是 1, 4, 7, 3, 6, 2, 5, 1.  当球重新回到1女孩手中时,每个人刚好只玩了一次.注:这个数字相当大(3 ≤ N ≤ 102000) 思路: 方法(1): 暴

ZOJ Monthly, June 2014 解题报告

A.Another Recurrence Sequence B.Gears 题目大意:有n个齿轮,一开始各自为一组,之后进行m次操作,包括以下4种类型: 1.合并两组齿轮,合并的两个应该反向旋转 2.把某个齿轮从所在组删除,自为一组,但不影响同组其它齿轮的状态与关系 3.询问两个齿轮是同向.反向或无关系(即不在同一组) 4.询问某个齿轮所在组的齿轮总数 分析:典型的并查集操作,但是注意两点: 1.由于操作3要询问两个齿轮的相对状态,因此对并查集中每个元素应当保存它的状态信息.状态是相对的,只需要