Codeforces Round #556 (Div. 2) - C. Prefix Sum Primes(思维)

Problem  Codeforces Round #556 (Div. 2) - D. Three Religions

Time Limit: 1000 mSec

Problem Description

Input

Output

Sample Input

5
1 2 1 2 1

Sample Output

1 1 1 2 2

题解:这个题有做慢了,这种题做慢了和没做出来区别不大。。。

  读题的时候脑子里还意识到素数除了2都是奇数,读完之后就脑子里就只剩欧拉筛了,贪心地构造使得前缀和是连续的素数,那实现就很简单了,将素数序列的差分序列求出来,不断凑出差分序列的每个数即可,但是之后想想,除了2 和 3,每个的间隔不都是偶数么,肯定是连续的2呀,费劲算差分序列干什么,直接先放2再放1不就行了(特殊处理一下2 和 3 即可),写着写着还误以为要输出下标,临时改了改,等到测样例的时候发现是输出1、2,暴风哭泣。

  1 #include <bits/stdc++.h>
  2
  3 using namespace std;
  4
  5 #define REP(i, n) for (int i = 1; i <= (n); i++)
  6 #define sqr(x) ((x) * (x))
  7
  8 const int maxn = 400000 + 10000;
  9 const int maxm = 200000 + 100;
 10 const int maxs = 10000 + 10;
 11
 12 typedef long long LL;
 13 typedef pair<int, int> pii;
 14 typedef pair<double, double> pdd;
 15
 16 const LL unit = 1LL;
 17 const int INF = 0x3f3f3f3f;
 18 const double eps = 1e-14;
 19 const double inf = 1e15;
 20 const double pi = acos(-1.0);
 21 const int SIZE = 100 + 5;
 22 const LL MOD = 1000000007;
 23
 24 LL n;
 25 LL a[maxn];
 26 int cnt[5];
 27 LL cnt1, cnt2;
 28 LL tot, prime[maxn];
 29 bool is_prime[maxn];
 30
 31 void Euler()
 32 {
 33     memset(is_prime, true, sizeof(is_prime));
 34     is_prime[0] = is_prime[1] = false;
 35     for (LL i = 2; i < maxn; i++)
 36     {
 37         if (is_prime[i])
 38         {
 39             prime[tot++] = i;
 40         }
 41         for (LL j = 0; j < tot && i * prime[j] < maxn; j++)
 42         {
 43             is_prime[prime[j] * i] = false;
 44             if (i % prime[j] == 0)
 45             {
 46                 break;
 47             }
 48         }
 49     }
 50 }
 51
 52 vector<int> ans;
 53 queue<int> que[3];
 54
 55 int main()
 56 {
 57     ios::sync_with_stdio(false);
 58     cin.tie(0);
 59     //freopen("input.txt", "r", stdin);
 60     //freopen("output.txt", "w", stdout);
 61     Euler();
 62     cin >> n;
 63     int x;
 64     LL sum = 0;
 65     for (int i = 1; i <= n; i++)
 66     {
 67         cin >> x;
 68         que[x].push(i);
 69         cnt[x]++;
 70         sum += x;
 71     }
 72     cnt1 = cnt[1], cnt2 = cnt[2];
 73     LL pre = 0;
 74     for (int i = 0; i < tot && prime[i] <= sum; i++)
 75     {
 76         LL tmp = prime[i] - pre;
 77         LL x = tmp / 2;
 78         x = min(x, cnt2);
 79         if (tmp - x * 2 <= cnt1)
 80         {
 81             pre = prime[i];
 82             for (int j = 0; j < x; j++)
 83             {
 84                 ans.push_back(2);
 85             }
 86             for (int j = 0; j < tmp - x * 2; j++)
 87             {
 88                 ans.push_back(1);
 89             }
 90             cnt2 -= x;
 91             cnt1 -= (tmp - x * 2);
 92         }
 93     }
 94     for(int i = 0; i < ans.size(); i++)
 95     {
 96         cout << ans[i] << " ";
 97     }
 98     while(cnt1--)
 99     {
100         cout << 1 << " ";
101     }
102     while(cnt2--)
103     {
104         cout << 2 << " ";
105     }
106     return 0;
107 }

原文地址:https://www.cnblogs.com/npugen/p/10798353.html

时间: 2024-11-06 22:05:23

Codeforces Round #556 (Div. 2) - C. Prefix Sum Primes(思维)的相关文章

Codeforces Round #556 (Div. 2) C. Prefix Sum Primes

题目大意让你改变数组的排序,使前缀和的素数最多: 这是一道模拟题,让你通过判断1和2的个数来解决, 只要特判一下1的个数是零的时候,2的个数是零的时候,或者1只有一个而2的个数又不是0个的时候,剩下的情况我们只有把1的个数分奇数和偶数来考虑,大致思路是这样,接下来就看代码吧 #include<iostream> #include<cstdio> #include<algorithm> #include<cstring> using namespace std

Codeforces Round #556 (Div. 2) - D. Three Religions(动态规划)

Problem  Codeforces Round #556 (Div. 2) - D. Three Religions Time Limit: 3000 mSec Problem Description Input Output Sample Input 6 8abdabc+ 1 a+ 1 d+ 2 b+ 2 c+ 3 a+ 3 b+ 1 c- 2 Sample Output YESYESYESYESYESYESNOYES 题解:动态规划,意识到这个题是动态规划之后难点在于要优化什么东西,本题

Codeforces Round #344 (Div. 2) E. Product Sum 二分斜率优化DP

E. Product Sum Blake is the boss of Kris, however, this doesn't spoil their friendship. They often gather at the bar to talk about intriguing problems about maximising some values. This time the problem is really special. You are given an array a of

Codeforces Round #319 (Div. 2) B Modulo Sum

直接O(n*m)的dp也可以直接跑过. 因为上最多跑到m就终止了,因为sum[i]取余数,i = 0,1,2,3...,m,会有m+1种可能,m的余数只有m种必然有两个相同. #include<bits/stdc++.h> using namespace std; const int maxn = 1e3+5; int cnt[maxn]; bool dp[maxn][maxn]; #define Y { puts("YES"); return 0; } int main(

Codeforces Round #575 (Div. 3) B. Odd Sum Segments (构造,数学)

B. Odd Sum Segments time limit per test3 seconds memory limit per test256 megabytes inputstandard input outputstandard output You are given an array a consisting of n integers a1,a2,-,an. You want to split it into exactly k non-empty non-intersecting

Codeforces Round #475 (Div. 2) C - Alternating Sum

等比数列求和一定要分类讨论!!!!!!!!!!!! 1 #include<bits/stdc++.h> 2 #define LL long long 3 #define fi first 4 #define se second 5 #define mk make_pair 6 #define pii pair<int,int> 7 #define ull unsigned long long 8 using namespace std; 9 10 const int N=1e6+7

Codeforces Round #556 (Div. 2)

没想到平成年代最后一场cf居然是手速场,幸好拿了个小号娱乐不然掉分预定 (逃 A: 傻题. 1 /* basic header */ 2 #include <iostream> 3 #include <cstdio> 4 #include <cstdlib> 5 #include <string> 6 #include <cstring> 7 #include <cmath> 8 #include <cstdint> 9

Codeforces Round #221 (Div. 2) D. Maximum Submatrix 2 (思维题)

题目地址:codeforces 221 D 这场是人生中做的第一场CF中的D题.(当时只做出来了A题..)过年之际回顾了一下,就顺便看了几道D题.现在做CF的D题在比赛时还是做不出来.但是赛后往往都可以自己做出来.据说D题能在比赛中稳出的话就可以区域赛银了.于是争取以后CF能稳出4道题吧. 这道题刚开始不该看标签的..给的是DP..于是就一直朝着DP方向想.但是感觉不像是DP.就换了个思路,就做出来了. 大体方法是先预处理出每一行中每个数向左延伸最长的连续1的个数.然后对每一行的进行排序(我这里

Codeforces Round #353 (Div. 2) C. Money Transfers (思维)

原题请戳这里 题意: n个银行成环形排列.每个银行有一定的余额ai,每次可以在任意相邻的银行间转账.问 最少需要经过多少次转账使得所有银行的余额都为0. 分析: 由于所有银行的余额总数为0,则若把整个环看成一段,需要n-1次使所有余额为0. 把ai分为k个sum=0的部分,每部分的长度为li,使每个部分所有银行清零需要li-1步.n个 银行清零总共需要n-k步. 因此即是求(n-k)min,那么k值越大越好. 考虑前缀和,若sum[i]==sum[j],则区间[i+1,j]必定和为0,且[j+1