列表

详情


NC218888. 谁是天选之人

描述

 

众所周知下棋是一个运气游戏,不过好像也是有规律可循的。

Graceful smiling cookies给它的n个棋子标序号,他决定以这些序号决定谁是天选。

最开始每个棋子标号都是0.

它要进行m次标序号。

  第i次标序号,它会将第(i X a+b)%n +1个棋子和第(i X b + a)%n +1个棋子之间的棋子都标上序号i。我会告诉你a和b的值,你可以告诉我最后每个棋子的颜色吗?


输入描述

一行四个整数 1=<n<=1e6 ,  1=<m<=1e7 ,  a  ,  b

保证:1<=m*a+b, m*b+a<=int最大值


输出描述

n行,每行表示第i个棋子的标号

示例1

输入:

3 2 1 3

输出:

0
2
2

原站题解

上次编辑到这里,代码来自缓存 点击恢复默认模板

C++ 解法, 执行用时: 2030ms, 内存消耗: 16008K, 提交时间: 2022-03-12 15:54:00

#include<bits/stdc++.h>
using namespace std;
const int N=1e6;
int g[N];
int d[N];
int n,m,a,b;
int main(){
	cin>>n>>m>>a>>b;
	for(int i=m;i>=1;i--){
		int x=(i*a+b)%n+1;
		int y=(i*b+a)%n+1;
		if(x>y) swap(x,y);
		for(int j=x;j<=y;j++){
			if(!d[j]){d[j]=y;g[j]=i;}
			else j=d[j];
		}
	}
	for(int i=1;i<=n;i++)	cout<<g[i]<<endl;
	return 0;
}

C(clang11) 解法, 执行用时: 151ms, 内存消耗: 15924K, 提交时间: 2021-03-07 16:08:39

#include<stdio.h>
int f[1000010],vis[1000010];
int main()
{
	int n,m,a,b;
	scanf("%d%d%d%d",&n,&m,&a,&b);
	for(int i=m;i;i--)
	{
		int s=(i*a+b)%n+1,t=(i*b+a)%n+1;
		if(s>t) {int k=s;s=t;t=k;}
		for(int j=s;j<=t;j++)
		{
			if(!vis[j])
			{
				f[j]=i;
				vis[j]=t;
			}
			else j=vis[j];
		}
	}
	for(int i=1;i<=n;i++) printf("%d\n",f[i]);
}

上一题