zoukankan      html  css  js  c++  java
  • Codeforces Round #268 (Div. 1) solution(upd div 1 C,div 2 A, B

    DIV2 :

    A.I Wanna Be the Guy

    题意:给你两列数和一个数k,问这两列数是否完全包含1-k。
    解法:可以排序之后模拟,我为了省掉排序和判断重复用了个set(我是set控~)。
    代码:
     1 #include <cstdio>
     2 #include <cstring>
     3 #include <set>
     4 #include <algorithm>
     5 using namespace std;
     6 
     7 set<int> s;
     8 set<int>::iterator it;
     9 
    10 int main() {
    11     int n, p;
    12     scanf("%d", &n);
    13     scanf("%d", &p);
    14     for(int i = 0; i < p; i++) { int a; scanf("%d", &a); s.insert(a);}
    15     scanf("%d", &p);
    16     for(int i = 0; i < p; i++) { int a; scanf("%d", &a); s.insert(a);}
    17     int c = 1;
    18     for(it = s.begin(); it != s.end(); it++) {
    19         if(*it == c) c++;
    20         else break;
    21     }
    22     if(c > n) puts("I become the guy.");
    23     else puts("Oh, my keyboard!");
    24 
    25     return 0;
    26 }
    View Code

    B.Chat Online

     题意:给你两个人的在线时间。一个人是固定的n个区间[a1, b1], [a2, b2], ..., [an,bn]。另一个人的在线时间是与起床时间t有关的m个区间,会输入l,r表示l <= t <= r。然后这个人的在线时间为[c1 + t, d1 + t], [c2 + t, d2 + t], ..., [cm + t, dm + t]。询问有多少个满足要求的起床时间使得两个人的在线时间有交集(只有一个时刻也可以)。
    解法:枚举t,之后判断区间组是否相交。为了好写我们可以对两个人的区间内的数都+1,然后扫描观察是否有等于2的数。
    代码:
     1 #include <cstdio>
     2 #include <cstring>
     3 #include <set>
     4 #include <algorithm>
     5 using namespace std;
     6 
     7 int u[1010], a[60], b[60], c[60], d[60];
     8 
     9 int main() {
    10     int p, q, l, r, ans = 0;
    11     scanf("%d%d%d%d", &p, &q, &l, &r);
    12     for(int i = 0; i < p; i++) scanf("%d%d", &a[i], &b[i]);
    13     for(int i = 0; i < q; i++) scanf("%d%d", &c[i], &d[i]);
    14     for(int i = l; i <= r; i++) {
    15         int f = 0;
    16         memset(u, 0, sizeof(u));
    17         for(int j = 0; j < p; j++) for(int t = a[j];  t <= b[j]; t++) u[t]++;
    18         for(int j = 0; j < q; j++) for(int t = c[j] + i;  t <= d[j] + i; t++) if(t <= 1000) u[t]++;
    19         for(int j = 0; j <= 1000; j++) if(u[j] >= 2) f = 1;
    20         ans += f;
    21     }
    22     printf("%d
    ", ans);
    23 
    24     return 0;
    25 }
    View Code

    DIV1:

    A.24 Game

    题意:给你1, 2, ..., n-1, n 这个序列,每次你可以取出两个数做+/-/*三种操作之一,然后把结果放回到序列中,询问能否是的这个序列最后只剩下一个24。

    解法:首先很明显n < 4的时候是无解的。如果n=4,那么1 * 2 * 3 * 4=24,如果n=5,那么(5 - 1 - 2) * 3 * 4 = 24。若n > 5,那么我可以做n - (n - 1) = 1,相当于变成了n-2时候的情况加一个1,那么显然最后让答案乘上这个1即可。
    代码:
    include <cstdio>
    #include <algorithm>
    #include <map>
    #include <vector>
    #include <string>
    #include <cstring>
    using namespace std;
    
    const int N = 500010;
    
    int a[N];
    
    
    int main() {
        int n;
        while( scanf("%d", &n) != EOF ) {
            if(n <= 3) { printf("NO
    "); continue; }
            else if(n % 2 == 0) {
                printf("YES
    ");
                int k = 0;
                for(int i = 5; i < n; i += 2) {
                    printf("%d - %d = 1
    ", i + 1, i);
                    k++;
                }
                printf("1 * 2 = 2
    ");
                printf("2 * 3 = 6
    ");
                printf("6 * 4 = 24
    ");
                for(int i = 0; i < k; i++) printf("1 * 24 = 24
    ");
            } else {
                printf("YES
    ");
                int k = 0;
                for(int i = 6; i < n; i += 2) {
                    printf("%d - %d = 1
    ", i + 1, i);
                    k++;
                }
                printf("5 - 1 = 4
    ");
                printf("4 - 2 = 2
    ");
                printf("2 * 3 = 6
    ");
                printf("6 * 4 = 24
    ");
                for(int i = 0; i < k; i++) printf("1 * 24 = 24
    ");
            }
        }
    
        return 0;
    }
    View Code

    B.Two Sets

    题意:给你一列两两不同的数v[i],然后两个正整数a,b,现在希望把序列v中的每个数都分到两个集合中的一个。假设两个集合为s,t,那么若x∈s,则a-x∈s,类似的有若x∈t,则b-x∈t。询问这列数能否被成功划分到两个集合。

    解法:首先我们假设a<b。我们考虑现在这列数中最小的数,假设为x。若b-x在序列v中存在,那么我一定会把x和b-x都放到集合t中。因为如果我不把b-x和x放到t中,那么b-x这个元素就永远无法被任何其他的元素匹配了。原因是假设又另一个元素能和b-x匹配,我们设这个元素为y,由于x是当前序列中的最小值,那么y>x,则有y+b-x>b,那么显然和y+b-x=b矛盾。然后还需要考虑的就是有可能2 * x = a或 2 * x = b,这种特殊考虑一下就好了。呃,我的代码由于没想清楚写的比较复杂,思路也不完全是上述的思路,仅供参考。
    代码:
    #include <cstdio>
    #include <algorithm>
    #include <map>
    #include <vector>
    #include <string>
    #include <set>
    #include <cstring>
    using namespace std;
    
    const int N = 100010;
    
    int v[N];
    map<int, int> mp;
    set<int> s;
    set<int>::iterator it, is, ir;
    
    int main() {
        int n, a, b;
        while( scanf("%d%d%d", &n, &a, &b) != EOF ) {
            int oo = 0;
            if(a > b) { swap(a, b); oo = 1; };
            s.clear();
            mp.clear();
            for(int i = 0; i < n; i++) {
                scanf("%d", &v[i]);
                s.insert(v[i]);
            }
            int flag = 0;
            for(it = s.begin(); s.size() > 0; it = s.begin()) {
                int p1 = *it;
                is = s.find(a - p1);
                if(2 * p1 == a) {
                    is = s.find(b - p1);
                    if(is != s.end()) {
                        s.erase(p1);
                        s.erase(b - p1);
                        mp[p1] = 1;
                        mp[b - p1] = 1;
                    } else {
                        s.erase(p1);
                        mp[p1] = 0;
                    }
                } else if(2 * p1 == b){
                    s.erase(p1);
                    mp[p1] = 1;
                }else if(is == s.end()) {
                    is = s.find(b - p1);
                    if(is == s.end()) {
                        if(2 * p1 == b) {
                            s.erase(p1);
                            mp[p1] = 1;
                        } else {
                            flag = 1;
                            break;
                        }
                    } else {
                        s.erase(b - p1);
                        s.erase(p1);
                        mp[b - p1] = 1;
                        mp[p1] = 1;
                    }
                } else {
                    is = s.find(b - p1);
                    if(is == s.end()) {
                        if(a - p1 == p1) {
                            flag = 1;
                            break;
                        }
                        s.erase(a - p1);
                        s.erase(p1);
                        mp[a - p1] = 0;
                        mp[p1] = 0;
                    } else {
                        is = s.find(b - a + p1);
                        if(is == s.end()) {
                            s.erase(a - p1);
                            s.erase(p1);
                            mp[a - p1] = 0;
                            mp[p1] = 0;
                        } else{
                            s.erase(b - p1);
                            s.erase(p1);
                            mp[b - p1] = 1;
                            mp[p1] = 1;
                            s.erase(a - p1);
                            s.erase(b - a + p1);
                            mp[a - p1] = 1;
                            mp[b - a + p1] = 1;
                        }
                    }
                }
            }
            if(flag == 1) printf("NO
    ");
            else {
                printf("YES
    ");
                for(int i = 0; i < n; i++) printf("%d%c", (mp[v[i]] ^ oo), (i == (n - 1))?'
    ':' ');
            }
        }
    
        return 0;
    }
    View Code

    C.Hack it!

    题意:设f(x) = x % 10 + f(x / 10), f(0) = 0。给定n,现在希望找到一组l,r(l < r) 使得( f(l)+f(l+1)+...+f(r) ) % n = 0。
    解法:我们考虑现在选择的区间为1-1000000,假设现在的sum % n = x。那么我把区间改为 2-1000001,答案显然会+1,因为f(1000001) - f(1) = 1,同理 f(1000000 + x) - f(x) = 1。所以我们可以通过把区间向右偏移n-x构造出答案。由于涉及到相乘爆long long我抄了个long long相乘的模板,当然也可以通过拆分乘的数然后每步取模来实现。
    代码:
     1 #include <cstdio>
     2 #include <cstring>
     3 #include <set>
     4 #include <algorithm>
     5 using namespace std;
     6 
     7 typedef long long ll;
     8 typedef const long long cll;
     9 
    10 ll mul_mod(ll a,ll b,cll &n){
    11         ll ans(0),tmp((a%n+n)%n); b=(b%n+n)%n;
    12         while(b){
    13             if(b&1)   if((ans+=tmp)>=n) ans-=n;
    14             if((tmp<<=1)>=n) tmp-=n;
    15             b>>=1;
    16         }  return ans;
    17 }
    18 int main() {
    19     ll a;
    20     scanf("%I64d", &a);
    21     ll p = 1;
    22     for(int i = 0; i < 19; i++) {
    23         p = mul_mod(p, 10LL, a);
    24     }
    25     p = mul_mod(p, 900LL, a);
    26     p += 1;
    27     p %= a;
    28     if(p) p = a - p;
    29     printf("%I64d 10%019I64d
    ", p + 1, p);
    30 
    31     return 0;
    32 }
    View Code
     
     
  • 相关阅读:
    QTP 处理webtable中的数据
    Error 1406.Setup cannot write the value Microsoft
    QTP打开WinTree中的指定节点
    Excel数据操作
    VBS中实现函数多返回值
    QTP的回放模式
    VBS中运行应用程序的两种方式及WshShell对像浅析
    程序员奇葩面试的奇葩问题
    Android如何实现毛玻璃效果之Android高级模糊技术
    Android通过用代码画虚线椭圆边框背景来学习一下shape的用法
  • 原文地址:https://www.cnblogs.com/shiina-mashiro/p/3984024.html
Copyright © 2011-2022 走看看