AtCoder Regular Contest 149 C.Avoid Prime Sum(构造题,补写法)

本文介绍了一种构造n*n矩阵的方法,确保任意两个相邻元素之和不是质数。提供了三种实现方案,包括规则构造、随机置换及分隔策略,并附带源代码。

题目

构造一个n*n(n<=1e3)的矩阵,恰用到1到n*n这n*n个数,

使得相邻两项之和不是质数

思路来源

官方题解/zhoukangyang代码/SSerxhs代码/Heltion代码

题解

自己虽然搞过去了,但是很复杂,多学学别人怎么写的

首先想到是奇数分一堆偶数分一堆,特判n=3后,分奇偶直接搞也可做

简洁的做法是特判n=3,4,5,然后n>=6用奇数和偶数中3的倍数做两堆数的分隔

此时奇数里3的倍数,偶数里3的倍数已经能独占一行了

代码1

中规中矩,n=3,4,5构造,n>=6按规则排一下序,很简洁

#include<bits/stdc++.h>
#define L(i, j, k) for(int i = (j); i <= (k); ++i)
#define R(i, j, k) for(int i = (j); i >= (k); --i)
#define ll long long
#define ull unsigned long long 
#define vi vector <int> 
#define sz(a) ((int) (a).size())
#define me(f, x) memset(f, x, sizeof(f))
using namespace std;
const int N = 1e6 + 7, mod = 998244353, inv3 = (mod + 1) / 3;
int n, m, w[N], ord[N];
int main () {
	ios :: sync_with_stdio(false);
	cin.tie (0); cout.tie (0);
	cin >> n;
	if(n == 3) {
		cout << "5 4 8\n";
		cout << "3 6 2\n";
		cout << "1 9 7\n";
		return 0;
	}
	if(n == 4) {
		cout << "15 11 16 12\n";
		cout << "13 3 6 9\n";
		cout << "14 7 8 1\n";
		cout << "4 2 10 5\n";
		return 0;
	}
	if(n == 5) {
		cout << "1 3 5 7 9\n";
		cout << "11 13 15 17 19\n";
		cout << "23 25 21 4 14\n";
		cout << "10 8 12 24 22\n";
		cout << "18 20 2 16 6\n";
		return 0;
	}
	L(i, 1, n * n) {
		if(i % 2 == 0) w[i] = 1e9 - (i % 3 == 0);
		else w[i] = (i % 3 == 0);
		ord[i] = i;
	}
	sort(ord + 1, ord + n * n + 1, [&] (int x, int y) {
		return w[x] < w[y];
	});
	L(i, 1, n * n) cout << ord[i] << " \n"[i % n == 0];
	return 0;
}
/*
6 2 5
5 2 3 1 4 6
*/

代码2

n=3,4,5直接暴力随机置换至有解

//这回只花了114514min就打完了。
//真好。记得多手造几组。ACM拍什么拍。 
#include "bits/std
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小衣同学

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值