nowcoder牛客wannafly挑战赛20

A---染色

签到题,设最终颜色为x,一次操作就需要把一个不是x的点变为x,所以最终颜色为x时需要操作 总结点个数-颜色为x的节点个数,然后枚举所有颜色就行了

  1 #include <iostream>
  2 #include <string.h>
  3 #include <cstdio>
  4 #include <vector>
  5 #include <map>
  6 #include <math.h>
  7 #include <string>
  8 #include <algorithm>
  9 #include <time.h>
 10  
 11 #define SIGMA_SIZE 26
 12 #define lson rt<<1
 13 #define rson rt<<1|1
 14 #define lowbit(x) (x&-x)
 15 #define foe(i, a, b) for(int i=a; i<=b; i++)
 16 #define fo(i, a, b) for(int i = a; i < b; i++);
 17 #pragma warning ( disable : 4996 )
 18  
 19 using namespace std;
 20 typedef long long LL;
 21 inline LL LMax(LL a,LL b)      { return a>b?a:b; }
 22 inline LL LMin(LL a,LL b)      { return a>b?b:a; }
 23 inline LL lgcd( LL a, LL b ) { return b==0?a:lgcd(b,a%b); }
 24 inline LL llcm( LL a, LL b ) { return a/lgcd(a,b)*b; }  //a*b = gcd*lcm
 25 inline int Max(int a,int b)    { return a>b?a:b; }
 26 inline int Min(int a,int b)    { return a>b?b:a; }
 27 inline int gcd( int a, int b ) { return b==0?a:gcd(b,a%b); }
 28 inline int lcm( int a, int b ) { return a/gcd(a,b)*b; }  //a*b = gcd*lcm
 29 const LL INF = 0x3f3f3f3f3f3f3f3f;
 30 const LL mod  = 1000000007;
 31 const double eps = 1e-8;
 32 const int inf  = 0x3f3f3f3f;
 33 const int maxk = 1e6+5;
 34 const int maxn = 1e5+5;
 35  
 36 int N, ct;
 37 int cnt[maxn];
 38 LL num[maxn];
 39 LL all;
 40 struct col {
 41     int id;
 42     LL val;
 43     col() {}
 44 }color[maxn];
 45  
 46 bool cmp(const col& a, const col& b)
 47 {
 48     return a.val < b.val;
 49 }
 50  
 51 void read()
 52 {
 53     memset(cnt, 0, sizeof(cnt));
 54     memset(num, 0, sizeof(num));
 55     all = 0;
 56  
 57     foe(i, 1, N)
 58     {
 59         scanf("%lld", &color[i].val);
 60         all += color[i].val;
 61         color[i].id = i;
 62     }
 63     sort(color+1, color+1+N, cmp);
 64  
 65     int x, y;
 66     foe(i, 1, N-1)
 67     {
 68         scanf("%d %d", &x, &y);
 69     }
 70 }
 71  
 72 int main()
 73 {
 74     while (~scanf("%d", &N))
 75     {
 76         read();
 77  
 78         LL tmp = color[1].val;
 79         num[1] = color[1].val;
 80         cnt[1] = 1;
 81         ct = 1;
 82         foe(i, 2, N)
 83         {
 84             if (color[i].val == tmp)
 85             {
 86                 cnt[ct]++;
 87                 continue;
 88             }
 89              
 90             tmp = color[i].val;
 91             num[++ct] = tmp;
 92             cnt[ct] = 1;
 93         }
 94  
 95         LL mmin = INF;
 96         foe(i, 1, ct)
 97         {
 98             tmp = all;
 99             tmp -= num[i]*cnt[i];
100             if (tmp >= mmin) continue;
101             tmp += (N-cnt[i])*num[i];
102             mmin = LMin(tmp, mmin);
103         }
104         printf("%lld\n", mmin);
105     }
106     return 0;
107 }
View Code

B---背包

我觉得这道题有点问题...先按价值排个序,然后考虑中位数两边最小的体积是多少呢,用优先队列从1~N扫一遍,再从N~1扫一遍,就可以记录下每个点往左和往右的所有物品中,取体积最小的M/2个物品的体积总和是多少,分别记为sum1[i],sum2[i],然后分奇偶讨论一下就行了(还是觉得数据有点问题,)

  1 #include <iostream>
  2 #include <string.h>
  3 #include <cstdio>
  4 #include <vector>
  5 #include <map>
  6 #include <queue>
  7 #include <math.h>
  8 #include <string>
  9 #include <algorithm>
 10 #include <time.h>
 11 
 12 #define SIGMA_SIZE 26
 13 #define lson rt<<1
 14 #define rson rt<<1|1
 15 #define lowbit(x) (x&-x)
 16 #define foe(i, a, b) for(int i=a; i<=b; i++)
 17 #define fo(i, a, b) for(int i = a; i < b; i++);
 18 #pragma warning ( disable : 4996 )
 19 
 20 using namespace std;
 21 typedef long long LL;
 22 inline LL LMax(LL a, LL b) { return a>b ? a : b; }
 23 inline LL LMin(LL a, LL b) { return a>b ? b : a; }
 24 inline LL lgcd(LL a, LL b) { return b == 0 ? a : lgcd(b, a%b); }
 25 inline LL llcm(LL a, LL b) { return a / lgcd(a, b)*b; }  //a*b = gcd*lcm
 26 inline int Max(int a, int b) { return a>b ? a : b; }
 27 inline int Min(int a, int b) { return a>b ? b : a; }
 28 inline int gcd(int a, int b) { return b == 0 ? a : gcd(b, a%b); }
 29 inline int lcm(int a, int b) { return a / gcd(a, b)*b; }  //a*b = gcd*lcm
 30 const LL INF = 0x3f3f3f3f3f3f3f3f;
 31 const LL mod = 1000000007;
 32 const double eps = 1e-8;
 33 const int inf = 0x3f3f3f3f;
 34 const int maxk = 1e6 + 5;
 35 const int maxn = 1e5 + 5;
 36 
 37 //优先队列默认从大到排列
 38 priority_queue<LL> qq;
 39 int V, N, M;
 40 LL sum;
 41 LL sum1[maxn], sum2[maxn];
 42 struct node {
 43     LL val, cost;
 44 }pp[maxn];
 45 
 46 bool cmp(const node& a, const node& b)
 47 {
 48     return a.val == b.val ? a.cost<b.cost : a.val<b.val;
 49 }
 50 
 51 void init()
 52 {
 53     foe(i, 1, N)
 54         scanf("%lld %lld", &pp[i].val, &pp[i].cost);
 55     sort(pp + 1, pp + 1 + N, cmp);
 56 }
 57 
 58 void solve(int i, int mid, LL ss[])
 59 {
 60     ss[i] = sum;
 61 
 62     sum += pp[i].cost;
 63     qq.push(pp[i].cost);
 64 
 65     if (qq.size() > mid) {
 66         sum -= qq.top();
 67         qq.pop();
 68     }
 69 }
 70 
 71 int main()
 72 {
 73     cin >> V >> N >> M;
 74 
 75     init();
 76 
 77     sum = 0;
 78     int mid = M / 2;
 79     //正向扫一遍
 80     for (int i = 1; i <= N; i++)
 81         solve(i, mid, sum1);
 82 
 83     sum = 0; while (!qq.empty()) qq.pop();
 84     //反向扫一遍
 85     for (int i = N; i >= 1; i--)
 86         solve(i, mid, sum2);
 87 
 88 
 89     if (M % 2) 
 90     {
 91         for (int i = N - mid; i >= mid + 1; i--)
 92             if (sum1[i] + sum2[i] + pp[i].cost <= V)
 93             {
 94                 printf("%lld\n", pp[i].val);
 95                 break;
 96             }
 97     }
 98     else 
 99     {
100         for (int i = N - mid + 1; i >= mid; i--)
101             if (sum1[i] + sum2[i - 1] <= V)
102             {
103                 printf("%lld\n", (pp[i].val + pp[i - 1].val) / 2);
104                 break;
105             }
106 
107     }
108 
109 
110     return 0;
111 }
View Code

 

posted @ 2018-07-24 22:49  LBNOQYX  阅读(181)  评论(0编辑  收藏  举报