noip2013/day1/1/转圈游戏

总时间限制: 
10000ms
 
单个测试点时间限制: 
1000ms
 
内存限制: 
128000kB
描述

n 个小伙伴(编号从 0 到 n-1)围坐一圈玩游戏。按照顺时针方向给 n 个位置编号,从 0 到 n-1。最初,第 0 号小伙伴在第 0 号位置,第 1 号小伙伴在第 1 号位置,……,依此类 推。

游戏规则如下:每一轮第 0 号位置上的小伙伴顺时针走到第 m 号位置,第 1 号位置小伙伴走到第 m+1 号位置,……,依此类推,第n − m号位置上的小伙伴走到第 0 号位置,第n-m+1 号位置上的小伙伴走到第1 号位置,……,第 n-1 号位置上的小伙伴顺时针走到第m-1 号位置。

现在,一共进行了 10k 轮,请问 x 号小伙伴最后走到了第几号位置。

输入
输入文件名为 circle.in。
输入共 1 行,包含 4 个整数 n、m、k、x,每两个整数之间用一个空格隔开。
输出
输出文件名为 circle.out。
输出共 1 行,包含 1 个整数,表示 10^k 轮后 x 号小伙伴所在的位置编号。
样例输入
10 3 4 5
样例输出
5
提示
对于 30%的数据,0 < k < 7; 
对于 80%的数据,0 < k < 10^7;
对于 100%的数据,1 < n< 1,000,000,0
来源
noip2013/day1/第一题
数学题注意取mod
#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;
const int maxn =  20003;
int m;
struct node{
    int v,next;
}edge[100000];int head[maxn],num;
void add_edge(int x ,int y)
{
    edge[++num].v=y;edge[num].next=head[x];head[x]=num;
}
bool vis[maxn];int son[maxn];
int siz=0x7fffffff,ans;
void dfs(int x)
{
    vis[x]=1;
    son[x]=0;
    int tmp=0;
    for(int i=head[x];i;i=edge[i].next)
    {
        int v=edge[i].v;
        if(vis[v])continue;
        dfs(v);
        son[x]+=(son[v]+1);
        tmp=max(son[v]+1,tmp);
    }
    tmp=max(tmp,m-son[x]-1);
    if(tmp<siz || tmp==siz && ans>x)
    {
        ans=x;
        siz=tmp;
    }
    
}
int main()
{
    int t;
    scanf("%d",&t);
    while(t--)
    {
        memset(vis,0,sizeof vis);num=0;siz=0x7fffffff;ans=0;
        memset(head,0,sizeof(head));
        scanf("%d",&m);
        int a,b;
        for(int i=1;i<m;i++)
        {
            scanf("%d%d",&a,&b);
            add_edge(a,b);add_edge(b,a);
        }
        dfs(1);
        printf("%d %d
",ans,siz);
    }
    return 0;
}
原文地址:https://www.cnblogs.com/sssy/p/7197109.html