AtCoder Regular Contest 149

A

发现所有数字都相同的数一共只有 106 种,考虑枚举每种情况,关键在于如何判断一个数 modm 是否为 0
考虑 9mod8=1,而 99mod8=(9×10+9)mod8=(10×(9mod8)+(9mod8))mod8=11mod8=3
可以递推。

点击查看代码
#include <bits/stdc++.h>
#define int long long
using namespace std;
int n,m,num,len;
signed main()
{
	cin>>n>>m;
	for(int i=1;i<=9;++i)
	{
		int tim=10,p=i%m;
		if(p==0)if(len<=1)len=1,num=i;
		for(int j=2;j<=n;++j)
		{
			p=(p+i*tim)%m;
			if(p==0)if(len<=j)len=j,num=i;
			tim=tim*10%m;
		}
	}
	if(len==0)cout<<-1;
	else for(int i=1;i<=len;++i)cout<<num;
	return 0;		
} 

B

比较 adhoc,结论:将一个数组从小到大排序,此时两个数组的 LIS 的和即为答案。
感性证明:考虑将数组重排,让第一个数组有序至少能让答案增大 1,在不能两个数组同时保证的情况下一定不劣。
答案即为 N+LIS(B)LIS 可以在 O(nlogn) 的时间内求出。

点击查看代码
#include <bits/stdc++.h>
using namespace std;
const int N=3e5+5;
struct node{int a,b;}num[N];
int n,b[N];
bool cmp(node q,node w){return q.a<w.a;}
int lowbit(int x){return x&-x;}
void add(int x,int k){while(x<=n)b[x]=max(b[x],k),x+=lowbit(x);}
int query(int x){int res=0;while(x)res=max(res,b[x]),x-=lowbit(x);return res;}
signed main()
{
	cin>>n;
	for(int i=1;i<=n;++i)cin>>num[i].a;
	for(int i=1;i<=n;++i)cin>>num[i].b;
	sort(num+1,num+n+1,cmp);
	int ans=0;
	for(int i=1;i<=n;++i)
	{
		int f=query(num[i].b)+1;
		ans=max(ans,f);add(num[i].b,f);
	}
	cout<<n+ans;
	return 0;
}

C

小清新构造。

让相邻两个的和不为质数,最简单的方法就是让和为偶数,容易知道 奇数+奇数=偶数,偶数+偶数=偶数,所以可以想到把奇数排在上面,偶数排在下面,尽可能减少奇数与偶数的接触。

下面,我们分类讨论 n 为奇数和偶数的情况。

n 为偶数

奇数都排在上面 n/2 行,偶数排在下面 n/2 行。但是,还有一个问题,第 n/2 行的数和第 n/2+1 行的数的和是奇数,可能会出现质数。
考虑如何构造,不难发现如果 n/2+1 行的数是 n/2 行的数的倍数,他们的和一定是合数,所以可以构造 n/2+1 行的数等于 n/2 行的数的二倍。剩下的数瞎填就好了。

3 5 7 9 11 13
6 10 14 18 22 26

n 为奇数

还像偶数一样,把奇数排在上面,偶数排在下面。
但是有一个问题(如下图,5×5 的格),(3,4) 的偶数同时与 (3,3),(2,4) 两个奇数相邻,(3,3) 的奇数也同时与两个偶数相邻,我们构造 3,6,9,12 就可以了。

9
3 6
12

剩下的位置继续构造 2 倍关系就可以了。

9 11
5 7 3 6 22
10 14 12

Corner Case

当然,n=3n=4 的情况需要特殊构造,具体构造方案见代码。

点击查看代码
#include <bits/stdc++.h>
using namespace std;
const int N=1005;
int n,a[N][N],used[N*N];
signed main()
{
	cin>>n;
	if(n==3){cout<<"5 9 1\n3 7 8\n6 2 4";return 0;}
	if(n==4){cout<<"9 11 13 15\n1 3 5 7\n8 6 10 14\n2 4 12 16";return 0;}
	if(n%2==0)
	{
		for(int i=1;i<=n;++i)
		{
			a[n/2][i]=i+i+1;
			a[n/2+1][i]=a[n/2][i]*2;
			used[i+i+1]=1;used[4*i+2]=1;
		}
		int now=1;
		for(int i=1;i<=n/2-1;++i)
			for(int j=1;j<=n;++j)
			{
				while(used[now])now+=2;
				a[i][j]=now;now+=2;
			}
		now=2;
		for(int i=n/2+2;i<=n;++i)
			for(int j=1;j<=n;++j)
			{
				while(used[now])now+=2;
				a[i][j]=now;now+=2;
			}
	}
	else
	{
		a[n/2+1][n/2+1]=3;used[3]=1;
		a[n/2+1][n/2+2]=6;used[6]=1;
		a[n/2][n/2+2]=9;used[9]=1;
		a[n/2+2][n/2+1]=12;used[12]=1;
		int now=5;
		for(int i=1;i<=n/2;++i)
		{
			while(used[now])now+=2;
			a[n/2+1][i]=now;a[n/2+2][i]=now*2;
			used[now]=1;used[now*2]=1;now+=2;
		}
		for(int i=n/2+3;i<=n;++i)
		{
			while(used[now])now+=2;
			a[n/2][i]=now;a[n/2+1][i]=now*2;
			used[now]=1;used[now*2]=1;now+=2;
		}
		now=1;
		for(int i=1;i<=n/2;++i)
			for(int j=1;j<=n;++j)
			{
				if(a[i][j])continue;
				while(used[now])now+=2;
				a[i][j]=now;now+=2;
			}
		now=2;
		for(int i=n/2+2;i<=n;++i)
			for(int j=1;j<=n;++j)
			{
				if(a[i][j])continue;
				while(used[now])now+=2;
				a[i][j]=now;now+=2;
			}
	}
	for(int i=1;i<=n;++i)
	{
		for(int j=1;j<=n;++j)
			cout<<a[i][j]<<" ";
		cout<<endl;
	}
	return 0;
}
posted @   lnwhl  阅读(53)  评论(1编辑  收藏  举报
相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现
点击右上角即可分享
微信分享提示