zoukankan      html  css  js  c++  java
  • 【codeforces】【比赛题解】#872 CF Round #440 (Div.2)

    链接

    【A】寻找漂亮数字

    题意:

    给定了两列非零数字。
    我们说一个数是漂亮的,当它的十进制表达中有至少一个数从数列一中取出,至少有一个数从数列二中取出。
    最小的漂亮数字是多少?

    输入:

    第一行两个数(n,m(1leq n,mleq9)),表示数列一、二的长度。
    第二行n个数,表示数列一。
    第三行m个数,表示数列二。

    题解:

     1 #include<cstdio>
     2 #include<algorithm>
     3 #include<cstring>
     4 #include<set>
     5 #define F(i,a,b) for(int i=a;i<=b;++i)
     6 #define dF(i,a,b) for(int i=a;i>=b;--i)
     7 #define F2(i,a,b) for(int i=a;i<b;++i)
     8 inline int Min(int p,int q){return p<q?p:q;}
     9 inline int Max(int p,int q){return p>q?p:q;}
    10 int n,m,a[10],b[10],A=100,B=100;
    11 void init(){
    12     int x;
    13     scanf("%d%d",&n,&m);
    14     F(i,1,n) scanf("%d",&x), a[x]=1, A=Min(A,x);
    15     F(i,1,m) scanf("%d",&x), b[x]=1, B=Min(B,x);
    16 }
    17 int main(){
    18     init();
    19     F(i,1,9) if(a[i]&&b[i]) {printf("%d",i); return 0;}
    20     if(A>B) printf("%d%d",B,A);
    21     else printf("%d%d",A,B);
    22     return 0;
    23 }

    【B】最小值的最大值的最大值

    题意:

    给定了一个数组和一个数k,你要把这个数组分成恰好k份,使得这k份中的每一份的最小值的最大值最大。
    求出这个最大值。

    输入:

    第一行,两个数n,k。
    第二行,n个数,表示数组中的元素。

    输出:

    一个数,表示最大值。

    题解:

    当k=1时,答案是最小值。当k>=3时,答案是最大值。
    当k=2时,枚举分割点。

     1 #include<cstdio>
     2 #include<algorithm>
     3 #include<cstring>
     4 #include<set>
     5 #define F(i,a,b) for(int i=a;i<=b;++i)
     6 #define dF(i,a,b) for(int i=a;i>=b;--i)
     7 #define F2(i,a,b) for(int i=a;i<b;++i)
     8 inline int Min(int p,int q){return p<q?p:q;}
     9 inline int Max(int p,int q){return p>q?p:q;}
    10 int n,k,a[100001],min=2147483647,max=-2147483647;
    11 int m1[100001],m2[100001];
    12 void init(){
    13     scanf("%d%d",&n,&k);
    14     F(i,1,n) scanf("%d",a+i), max=Max(max,a[i]), min=Min(min,a[i]);
    15 }
    16 int main(){
    17     init();
    18     if(k>=3) printf("%d",max);
    19     else if(k==1) printf("%d",min);
    20     else{
    21         m1[1]=a[1]; F(i,2,n) m1[i]=Min(m1[i-1],a[i]);
    22         m2[n]=a[n]; dF(i,n-1,1) m2[i]=Min(m2[i+1],a[i]);
    23         int Ans=-2147483647;
    24         F(i,2,n) Ans=Max(Ans,Max(m1[i-1],m2[i]));
    25         printf("%d",Ans);
    26     }
    27     return 0;
    28 }

    【C】最大分割

    题意:

    给你一个数n,把它分成若干个合数的和,最多能分成多少个合数?有多组数据。

    输入:

    第一行一个数q(1<=q<=10^5),表示数据组数。
    对于每个数据,输入一个数n(1<=n<=10^9)。

    输出:

    对于每组数据,输出一行一个数表示分割数。如果无法做到,输出-1。

    题解:

    4是最小的合数,对于n足够大的情况,可以分成若干4和一些较小的合数。
    于是对4的余数分类讨论。具体看代码。

     1 #include<cstdio>
     2 #include<algorithm>
     3 #include<cstring>
     4 #include<set>
     5 #define F(i,a,b) for(int i=a;i<=b;++i)
     6 #define dF(i,a,b) for(int i=a;i>=b;--i)
     7 #define F2(i,a,b) for(int i=a;i<b;++i)
     8 inline int Min(int p,int q){return p<q?p:q;}
     9 inline int Max(int p,int q){return p>q?p:q;}
    10 int T,n;
    11 int main(){
    12     scanf("%d",&T);
    13     while(T--){
    14         scanf("%d",&n);
    15         switch(n%4){
    16             case 0: printf("%d
    ",n/4);break;
    17             case 1: {n>=9?printf("%d
    ",(n-9)/4+1):puts("-1");break;}
    18             case 2: {n>=6?printf("%d
    ",(n-6)/4+1):puts("-1");break;}
    19             case 3: {n>=15?printf("%d
    ",(n-15)/4+2):puts("-1");break;}
    20         }
    21     }
    22     return 0;
    23 }

    【D】和区间与异或有关的东西

    不会。

    【E】点、线什么的和现成的标题

    题意:

    平面直角坐标系中有一些格点,你可以过每个格点画出关于x轴y轴平行的直线,也可以不画,问有最终多少种不同的画法,重合的直线算作同一条。

    输入:

    第一行,一个数n(1<=n<=10^5),表示格点的个数。

    接下来n行,每行两个数xi, yi,表示第i个点的坐标是(xi,yi)。保证没有重合的点。

    输出:

    一个数,画法总数对10^9+7取模的结果。

    题解:

    只有横坐标或纵坐标相同的点才会互相影响,而互相影响的关系是传递的。
    我们先把不会互相影响的点分开,最终的答案是每一部分的答案的乘积。
    那么现在我们有一堆互相影响的点,如何计算方案数?

    参见http://www.cnblogs.com/kkkkahlua/p/7679526.htmlhttp://hzwer.com/2950.html。嘻嘻。

    代码也是抄的,嘤嘤嘤。

     1 #include <bits/stdc++.h>
     2 #define maxn 100010
     3 using namespace std;
     4 typedef long long LL;
     5 const LL mod = 1e9+7;
     6 struct node {
     7     int x, y;
     8 }a[maxn];
     9 int fa[maxn], sz[maxn], f[maxn], id[maxn], m[maxn];
    10 bool circ[maxn], vis[maxn];
    11 vector<int> v[maxn];
    12 set<int> sx, sy;
    13 bool cmp1(int i, int j) {
    14     return a[i].x < a[j].x || (a[i].x == a[j].x && a[i].y < a[j].y);
    15 }
    16 bool cmp2(int i, int j) {
    17     return a[i].y < a[j].y || (a[i].y == a[j].y && a[i].x < a[j].x);
    18 }
    19 LL poww(LL a, LL b) {
    20     LL ret = 1;
    21     while (b) {
    22         if (b & 1) (ret *= a) %= mod;
    23         (a *= a) %= mod;
    24         b >>= 1;
    25     }
    26     return ret;
    27 }
    28 int find(int x) { return fa[x] == x ? x : fa[x] = find(fa[x]); }
    29 void unionn(int a, int b) {
    30     a = find(a), b = find(b);
    31     if (a == b) { circ[a] = true; return; }
    32     if (sz[a] > sz[b]) swap(a, b);
    33     fa[a] = b; sz[b] += sz[a];
    34     circ[b] |= circ[a];
    35 }
    36 int main() {
    37     int n;
    38     scanf("%d", &n);
    39     for (int i = 0; i < n; ++i) {
    40         scanf("%d%d", &a[i].x, &a[i].y);
    41     }
    42     for (int i = 0; i < n; ++i) id[i] = i;
    43     for (int i = 0; i < n; ++i) fa[i] = i, sz[i] = 1;
    44 
    45     sort(id, id+n, cmp1);
    46     for (int i = 1; i < n; ++i) {
    47         if (a[id[i]].x == a[id[i-1]].x) unionn(id[i-1], id[i]);
    48     }
    49     sort(id, id+n, cmp2);
    50     for (int i = 1; i < n; ++i) {
    51         if (a[id[i]].y == a[id[i-1]].y) unionn(id[i-1], id[i]);
    52     }
    53     for (int i = 0; i < n; ++i) fa[i] = find(i);
    54 
    55     int tot = -1;
    56     for (int i = 0; i < n; ++i) {
    57         if (!vis[fa[i]]) vis[fa[i]] = true, f[++tot] = fa[i], m[fa[i]] = tot;
    58         v[m[fa[i]]].push_back(i);
    59     }
    60     LL ans = 1;
    61     for (int i = 0; i <= tot; ++i) {
    62         sx.clear(), sy.clear();
    63         for (auto idx : v[i]) {
    64             sx.insert(a[idx].x), sy.insert(a[idx].y);
    65         }
    66         LL mul = poww(2, sx.size()+sy.size());
    67         if (!circ[f[i]]) (mul += mod-1) %= mod;
    68         (ans *= mul) %= mod;
    69     }
    70     printf("%I64d
    ", ans);
    71     return 0;
    72 }
  • 相关阅读:
    PHP中逻辑运算符and/or与||/&&的一个坑
    PHP usort 使用用户自定义的比较函数对数组中的值进行排序
    php编写TCP服务端和客户端程序
    Redis系列-php怎么通过redis扩展使用redis
    国内镜像源收集
    双通道内存技术简介
    收集些日本的VPS
    建站相关关键词快速普及
    bash 的漏洞,你们中招了吗?
    戴维·卡梅伦(David William Donald Cameron)经典语录
  • 原文地址:https://www.cnblogs.com/PinkRabbit/p/7695725.html
Copyright © 2011-2022 走看看