Codeforces Round #268 (Div. 1) solution(upd div 1 C,div 2 A, B - 14.9.29)

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\n", 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\n"); continue; }
        else if(n % 2 == 0) {
            printf("YES\n");
            int k = 0;
            for(int i = 5; i < n; i += 2) {
                printf("%d - %d = 1\n", i + 1, i);
                k++;
            }
            printf("1 * 2 = 2\n");
            printf("2 * 3 = 6\n");
            printf("6 * 4 = 24\n");
            for(int i = 0; i < k; i++) printf("1 * 24 = 24\n");
        } else {
            printf("YES\n");
            int k = 0;
            for(int i = 6; i < n; i += 2) {
                printf("%d - %d = 1\n", i + 1, i);
                k++;
            }
            printf("5 - 1 = 4\n");
            printf("4 - 2 = 2\n");
            printf("2 * 3 = 6\n");
            printf("6 * 4 = 24\n");
            for(int i = 0; i < k; i++) printf("1 * 24 = 24\n");
        }
    }

    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\n");
        else {
            printf("YES\n");
            for(int i = 0; i < n; i++) printf("%d%c", (mp[v[i]] ^ oo), (i == (n - 1))?'\n':' ');
        }
    }

    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\n", p + 1, p);
30 
31     return 0;
32 }
View Code

 

 
 
posted @ 2014-09-21 00:23  shiina mashiro  阅读(296)  评论(0编辑  收藏  举报