Codeforces Round #671 (Div. 2) D1/2、E

D1/2(Sage’s Birthday)

题意:给定序列 a n a_n an,要求重新排序,让谷最多,即( a i − 1 < a i < a i + 1 a_{i-1}<a_i<a_{i+1} ai1<ai<ai+1)。输出序列并且给出最多的个数。
D 1 和 2 的 区 别 是 e a s y 版 本 里 面 的 数 字 大 小 不 一 样 , h a r d 可 能 相 同 D1和2的区别是easy版本里面的数字大小不一样,hard可能相同 D12easyhard
思路:
不一样的时候能够想到是分奇数和偶数位置,sort以后在偶数位置从 a 1 a_1 a1开始递增放入序列,奇数位置也是按着递增把剩下的放入。
一样的化手推发现可能就是有几个原来的位置不作数了,我就来了两遍,第一个是上面的做法,记录谷的个数从solve返回;第二种把原来的奇数位置反向放(递减),再来一遍记录答案 o u t out out。比较大小输出
正确性婷婷也不知道^^

int n, a[maxn], ans[maxn], ans1[maxn];
int solve() {
    
    
	int nw = 0, co = 0;
	for (int i = 2; i <= n; i += 2) {
    
    
		ans1[i] = a[++nw];
	}
	for (int i = 1; i <= n; i += 2) {
    
    
		ans1[i] = a[++nw];
	}
	for (int i = 2; i <= n; i += 2) {
    
    
		if (ans1[i] < ans1[i + 1] && ans1[i] < ans1[i - 1])co++;
	}
	return co;
}
int main() {
    
    
	int  head = 0;
	cin >> n;
	int w = n + 1, out = 0;
	for (int i = 1; i <= n; i++)cin >> a[i];
	sort(a + 1, a + 1 + n);
	for (int i = 1; i <= n; i+=2) {
    
    
		ans[i] = a[--w];
	}
	for (int i = 2; i <= n; i += 2) {
    
    
		ans[i] = a[++head];
		if (ans[i] < ans[i + 1] && ans[i] < ans[i - 1])out++;
	}
	int a1 = solve();
	if (out > a1) {
    
    
		cout << out << endl;
		for (int i = 1; i <= n; i++) {
    
    
			cout << ans[i] << " ";
		}
		cout << endl;
	}
	else {
    
    
		cout << a1 << endl;
		for (int i = 1; i <= n; i++) {
    
    
			cout << ans1[i] << " ";
		}
		cout << endl;
	}
	return 0;
}

E. Decryption(因数分解、构造)

link
题意:给定合数 n n n,把他们的因子分出来,自己排顺序放在一个环上。要求相邻的数字 g c d ≠ 1 gcd\ne1 gcd=1。可以进行另外的向两数插入 l c m lcm lcm的操作。要求输出最小的操作数的序列
思路:都已经开始合数了必然开素数或者因数分解。但是 n ≤ 1 0 9 n\le10^9 n109,应该不能线性筛上了。

  1. 考虑用 n \sqrt{n} n 筛出他的因子(不包括素数) f a c i fac_i faci,找出因子的同时判断是不是素数( f a c i \sqrt{fac_i} faci 判断),是的化存到 p i p_i pi.我对他们进行了去重,考虑到之后可能有素数的次数 ≠ 1 \ne1 =1
  2. 操作数最小只可能有两种情况: ( a ) (a) a合数由两个次数为1的素数组成,操作数1 ( b ) (b) b其他,操作数为0
  3. 构造:数轴上放去重之后的素数组 p n p_n pn,在两个 p i 与 p i + 1 ( i < s u m p ( 素 数 总 个 数 ) ) p_i与p_{i+1}(i<sump(素数总个数)) pipi+1(i<sump())之间先放上 f a c n fac_n facn中不等于 去 素 数 因 子 组 p i ∗ p i + 1 去素数因子组p_i*p_{i+1} pipi+1 包 含 p i 包含p_i pi的合数,然后放上 p i ∗ p i + 1 p_i*p_{i+1} pipi+1。在 p s u m p p_{sump} psump与n之间把余下的放上,记得去重
int n;
int p[maxn], fac[maxn];
map<int, int>vis, facp, pp;
int main() {
    
    
	int T;
	int sumfac, sump, minn, flag, anss, tt;
	cin >> T;
	//primes((int)(sqrt(1e9)));
	while (T--)
	{
    
    
		cin >> n;
		vis.clear();
		facp.clear();
		pp.clear();
		sumfac = 0; sump = 0;

		for (int i = 2; (LL)i*i <= (LL)n; i++) {
    
    
			if (n%i == 0) {
    
    
				/*fac[++sumfac] = i;
				if (n / i != i)fac[++sumfac] = n / i;*/
				flag = 0;
				minn = i;
				for (int j = 2; (LL)j*j <= (LL)minn; j++) {
    
    
					if (minn%j == 0) {
    
    
						flag = 1;
						break;
					}
				}
				if (!flag) {
    
     if(pp[minn]==0)p[++sump] = minn; pp[minn]++; }
				else {
    
     if (facp[minn] == 0)fac[++sumfac] = minn; facp[minn] = 1; }
				flag = 0;
				minn = n / i;
				for (int j = 2; (LL)j*j <= (LL)minn; j++) {
    
    
					if (minn%j == 0) {
    
    
						flag = 1;
						break;
					}
				}
				if (!flag) {
    
     if (pp[minn] == 0)p[++sump] = minn; pp[minn]++; }
				else {
    
     if (facp[minn] == 0)fac[++sumfac] = minn; facp[minn] = 1; }
			}
		}
		if (sump == 2 && sumfac == 0) {
    
    
			
			cout << p[1] << " " << p[2] << " " << n << endl;
			cout << 1 << endl;
			continue;
		}
		for (int i = 1; i < sump; i++) {
    
    
			if (vis[p[i]])continue;
			cout << p[i] << " ";
			vis[p[i]] = 1;
			//ans[++anss] = p[i];
			for (int j = 1; j <= sumfac; j++) {
    
    
				if (fac[j] % p[i] == 0 && fac[j] != p[i] * p[i + 1] && vis[fac[j]] == 0) {
    
     cout << fac[j] << " "; vis[fac[j]] = 1; }
			}
			if (vis[p[i] * p[i + 1]] == 0) {
    
     cout << p[i] * p[i + 1] << " "; vis[p[i] * p[i + 1]] = 1; }
			//ans[++anss] = p[i] * p[i + 1];
		}
		cout << p[sump] << " ";
		for (int i = 1; i <= sumfac; i++) {
    
    
			if (fac[i] % p[sump] == 0 && vis[fac[i]] == 0) {
    
     cout << fac[i] << " "; vis[fac[i]] = 1; }
		}
		cout << n << endl;
		cout << 0 << endl;
		//ans[++anss] = n;
	}
	return 0;
}

猜你喜欢

转载自blog.csdn.net/weixin_44986601/article/details/108752718