寒假训练1解题报告

1.CodeForces 92A

给一堆围成圈的小朋友发饼干,小朋友为1~n号,第几号小朋友每次拿多少块饼干,问最后剩多少饼干

#include <iostream>
#include <cstdio>
using namespace std;

int main()
{
   // freopen("a.in" , "r" , stdin);
    int n , m;
    while(scanf("%d%d" , &n , &m) == 2)
    {
        int tmp = (1 + n ) * n / 2;
        m %= tmp;
        for(int i=1 ; i<=n ; i++){
            if(m >= i) m-=i;
            else break;
        }
        printf("%d\n" , m);
    }
    return 0;
}

2.CodeForces 96A

用0,1分别代表己方和对方球员,如果有7个及以上的同队队员站一起会危险,问是否处于危险状态

#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
const int N = 105;
char s[N];
int pos[N];

int main()
{
   // freopen("a.in" , "r" , stdin);
    while(scanf("%s" , s) != EOF)
    {
        int len = strlen(s);
        for(int i=0 ; i<len ; i++){
            if(s[i] == ‘0‘) pos[i] = 0;
            else pos[i] = 1;
        }

        int flag = pos[0] , cnt = 1;
        bool ok = true;
        for(int i=1 ; i<len ; i++){
            if(pos[i] == flag){
                cnt++;
                if(cnt >= 7){
                    ok = false;
                    break;
                }
            }
            else{
                flag = pos[i];
                cnt = 1;
            }
        }

        if(ok) puts("NO");
        else puts("YES");
    }
    return 0;
}

3.CodeForces 71A

将字符串按某种规则缩写

#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
const int N = 105;
char s[N];

int main()
{
  //  freopen("a.in" , "r" , stdin);
    int T;
    scanf("%d" , &T);
    while(T--)
    {
        scanf("%s" , s);
        int len = strlen(s);
        if(len <= 10){
            printf("%s\n" , s);
            continue;
        }
        printf("%c%d%c\n" , s[0] , len-2, s[len-1]);
    }
    return 0;
}

4.CodeForces 71B

枚举所有可能的值就可以了

#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
const int N = 105;
int val[N];

int main()
{
   // freopen("a.in" , "r" , stdin);
    int n , k , t;
    while(scanf("%d%d%d" , &n , &k , &t) == 3)
    {
        int tmp = k*n*t , p , q;
        memset(val , 0 , sizeof(val));
        for(p=0 ; p<=n ; p++){
            int flag = 0;
            for(q=0 ; q<=k ; q++){
                int tmp1 = 100*p*k + 100 * q;
              //  cout<<"tmp: "<<tmp<<" "<<tmp1<<endl;
                if(tmp >= tmp1 && tmp<tmp1+100){
                    flag= 1;
                    break;
                }
            }
            if(flag) break;
        }
      //  cout<<p<<" "<<q<<endl;
        for(int i=1 ; i<=p ; i++)
            val[i] = k;
        val[p+1] = q;
        for(int i=1 ; i<=n ; i++)
            if(i == 1) printf("%d" , val[i]);
            else printf(" %d" ,val[i]);
        puts("");
    }
    return 0;
}

5.CodeForces 71C

枚举所有的因子,然后令每个数都对这个因子取模,观察模相同的数是否等于总数除以因子

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
using namespace std;
const int N = 100005;
int vis[N] , mul[N] , cnt , a[N] , tot[N];

void cal(int n)
{
    int t = (int)sqrt(n);
    cnt = 0;
    if(n % 4==0){
        mul[cnt++] = 4;
    }
    while(n % 2 == 0) n>>=1;
    for(int i=3 ; i<=t ; i++){
        if(n % i == 0){
            mul[cnt++] = i;
            while(n % i == 0)n/=i;
        }
        if(i > n) break;
    }
    if(n>1) mul[cnt++] = n;
}

int main()
{
  //  freopen("a.in" , "r" , stdin);
    int n , x;
    while(~scanf("%d" , &n))
    {
        int k=0;
        for(int i=0 ; i< n;i++){
            scanf("%d" , &x);
            if(x == 1) a[k++] = i;
        }
        cal(n);
        int flag = 0;

        for(int i=0 ; i<cnt ; i++)
        {
            int tmp = n/mul[i];
            memset(tot , 0 , sizeof(tot));
            for(int j=0 ; j<k ; j++){
                int pp = a[j] % tmp;
                tot[pp] ++;
                if(tot[pp] == mul[i]){
                    flag = 1;
                    break;
                }
            }
            if(flag) break;
        }
        if(flag) puts("YES");
        else puts("NO");
    }
    return 0;
}

6.CodeForces 71D

纯模拟,代码量略长

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int N = 60;

char str[4];
int num[N][N] , vis[N];
int cnt; //记录可行矩阵的个数

struct Node{
    int x,y;
}node[60];

Node pos1 , pos2;
Node squre1 , squre2;

int change1(char c)
{
    if(c == ‘C‘) return 0;
    else if(c == ‘D‘) return 1;
    else if(c == ‘H‘) return 2;
    else if(c == ‘S‘) return 3;
}

int change2(char c)
{
    if(c == ‘A‘) return 0;
    else if(c == ‘T‘) return 9;
    else if(c == ‘J‘) return 10;
    else if(c == ‘Q‘) return 11;
    else if(c == ‘K‘) return 12;
    else {
        return (int)(c-‘1‘);
    }
}

bool ok(int i , int j)
{
    int flag1 = 1 , flag2 = 1;
    int mod[20];
    memset(mod, 0 , sizeof(mod));
    for(int p=0 ; p<3 ; p++){
        for(int q=0 ; q<3 ; q++){
            int t = num[i+p][j+q] % 13;
            if(mod[t]){
                flag1 = 0;
                break;
            }
            mod[t] = 1;
        }
        if(!flag1) break;
    }
    if(flag1) return true;

    int col = num[i][j] / 13;
    for(int p=0 ; p<3 ; p++){
        for(int q=0 ; q<3 ; q++){
            int t = num[i+p][j+q] / 13;
            if(t != col){
                flag2 = 0;
                break;
            }
        }
        if(!flag2) break;
    }

    if(flag2) return true;
    else return false;
}

bool ok1(Node m1 , Node m2)
{
    if(m1.x > m2.x+2) return true;
    if(m1.x+2 < m2.x) return true;
    if(m1.y+2 < m2.y) return true;
    if(m1.y > m2.y+2) return true;
    return false;
}

void get_martrix(int n , int m)
{
    cnt = 0;
    for(int i=1 ; i<=n-2 ; i++){
        for(int j=1 ; j<=m-2 ; j++){
            if(ok(i,j)){
                node[cnt].x = i;
                node[cnt++].y = j;
            }
        }
    }
}

char* intTostring(int x)
{
    char *s = new char [3];
    int t1 = x/13;
    if(t1 == 0) s[1] = ‘C‘;
    else if(t1 == 1) s[1] = ‘D‘;
    else if(t1 == 2) s[1] = ‘H‘;
    else if(t1 == 3) s[1] = ‘S‘;

    int t2 = x%13;
    if(t2 == 0) s[0] = ‘A‘;
    else if(t2 == 9) s[0] = ‘T‘;
    else if(t2 == 10) s[0] = ‘J‘;
    else if(t2 == 11) s[0] = ‘Q‘;
    else if(t2 == 12) s[0] = ‘K‘;
    else {
        s[0] = (char)(t2+‘1‘);
    }
    s[2] = ‘\0‘;
    return s;
}

int main()
{
   // freopen("a.in" , "r" , stdin);
    int n , m;
    while(scanf("%d%d" , &n , &m) == 2)
    {
        bool flag1 = false , flag2 = false;
        int ans1 , ans2 , card1 , card2;//记录最后选中的在第几号节点
        pos1.x = pos1.y = pos2.x = pos2.y = 0;
        memset(vis , 0 , sizeof(vis));

        for(int i=1 ; i<=n ; i++)
            for(int j = 1 ; j<=m ; j++)
            {
                scanf("%s" , str);
                if(str[1] == ‘1‘){
                    pos1.x = i;
                    pos1.y = j;
                    flag1 = true;
                }
                else if(str[1] == ‘2‘){
                    pos2.x = i;
                    pos2.y = j;
                    flag2 = true;
                }
                else{
                    num[i][j] = 13*change1(str[1]) + change2(str[0]);
                    vis[num[i][j]] = 1;
                }
            }
       /* for(int i=1 ; i<=n ; i++){
            for(int j = 1 ; j<=m ; j++)
                cout<<num[i][j]<<" ";

            puts("");
        }*/
        bool find = false;
        int time=0;
        if(flag1) time++;
        if(flag2) time++;
        for(int p=0 ; p<52 ; p++){
            for(int q=0 ; q<52 ; q++){
                if(p == q) continue;
                int change = time;
                if(flag1 && !vis[p]) num[pos1.x][pos1.y] = p,change--;
                if(flag2 && !vis[q]) num[pos2.x][pos2.y] = q,change--;

                if(!change)
                {
                    get_martrix(n , m);

                    for(int i=0 ; i<cnt ; i++){
                        for(int j=i+1 ; j<cnt ; j++){
                            if(ok1(node[i] , node[j])){
                                find=true;
                                ans1 = i , ans2 = j;
                                card1 = p , card2 = q;
                                break;
                            }
                        }
                        if(find) break;
                    }

                }
                if(find) break;
            }
            if(find) break;
        }

        if(!find)
            puts("No solution.");
        else{
            puts("Solution exists.");
            if(!flag1 && !flag2){
                puts("There are no jokers.");
            }
            else if(flag1 && flag2){
                char *s1 = new char [3];
                char *s2 = new char [3];
                s1 = intTostring(card1);
                s2 = intTostring(card2);
                printf("Replace J1 with %s and J2 with %s.\n" , s1 , s2);
            }
            else if(flag1){
                char *s1 = new char [3];
                s1 = intTostring(card1);
                printf("Replace J1 with %s.\n" , s1);
            }
            else if(flag2){
                char *s1 = new char [3];
                s1 = intTostring(card2);
                printf("Replace J2 with %s.\n" , s1);
            }
            printf("Put the first square to (%d, %d).\n" , node[ans1].x , node[ans1].y);
            printf("Put the second square to (%d, %d).\n" , node[ans2].x , node[ans2].y);
        }
    }
    return 0;
}

7.CodeForces 88E

一道简单的nim博弈,sg函数值的计算过程中注意保存得到的最小堆数,过程可以用异或的前缀和帮助自己提高效率

#include <cstdio>
#include <cstring>
#include <iostream>
#include <cmath>
using namespace std;
const int N = 100010;

int sg[N] , sum[N] , minn[N] , vis[N];

void init_sg()
{
    sg[0] = sg[1] = sg[2] = 0;
    sum[0] = sum[1] = sum[2] = 0;
    memset(minn , 0x3f , sizeof(minn));
    for(int n=3 ; n<=100000 ; n++){
        int t = 2*n;
        int factor = (int)(sqrt(t+0.5));
        for(int k=2 ; k<=factor ; k++){
            if(t % k == 0 && t/k+1-k>0 && !((t/k+1-k)&1)){
                int a = (t/k+1-k)/2;
                int p = sum[a+k-1]^sum[a-1];
                vis[p] = n;
                if(p == 0) minn[n] = min(minn[n] , k);
            }
        }
        //找没有出现过的最小的sg函数
        int v = 0;
        while(1){
            if(vis[v] != n){
                sg[n] = v;
                break;
            }
            v++;
        }
        //记录当前的sum[]前缀
        sum[n] = sum[n-1]^sg[n];
    }
}

int main()
{
  //  freopen("a.in" , "r" , stdin);
    init_sg();
    int n;
    while(scanf("%d" , &n) == 1)
    {
        if(!sg[n]){
            puts("-1");
            continue;
        }
        printf("%d\n" , minn[n]);
    }
    return 0;
}

时间: 2024-11-14 22:39:22

寒假训练1解题报告的相关文章

寒假训练5解题报告

1.HDU 1114 Piggy Bank 一道简单的背包问题 #include <iostream> #include <cstdio> #include <cstring> using namespace std; #define ll long long const int N = 10005; const int INF = 0x3f3f3f3f; int dp[N]; int main() { // freopen("a.in" , &qu

寒假训练3解题报告 CodeForces #148

CodeForces 148B 一道简单模拟,判断龙能够抓到公主几次,如果公主和龙同时到达公主的城堡,不算龙抓住她,因为路程除以速度可能会产生浮点数,所以这里考虑一下精度问题 1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <iomanip> 5 #include <algorithm> 6 using namespace std; 7 #defi

寒假训练4解题报告

1.        Cosmic Tables 数据量比较大,这里不能直接暴力,用行指针和列指针表示当前行列是原来的第几行第几列 #include <cstdio> #include <cstring> #include <iostream> using namespace std; const int N = 1005; int n ,m , k , row[N] , col[N] , a[N][N]; char s[5] ; int p1 , p2; int mai

寒假训练2解题报告

1.CodeForces 112C 找一种可能满足其所给条件,为了让平方和尽可能大,那么我们总和总是取最大为y,分这个y时,尽可能少分这样得到的平方和才最大,所以其他元素都只分到1,留下一个最大元素,这里注意如果每个都分1不够分,直接表示无答案 #include <iostream> #include <cstring> #include <cstdio> using namespace std; #define ll long long const int N = 1

广大暑假训练1 E题 Paid Roads(poj 3411) 解题报告

题目链接:http://poj.org/problem?id=3411 题目意思:N个city 由 m 条路连接,对于一条路(假设连接Cityia和 Cityb),如果从Citya 去 Cityb的途中,之前已经走过Cityc(可能会等于a),那么就可以交p的钱,否则之前未走过Cityc,就一定要交r 的路费啦. 注意,一个点可以被反复多次走,也就是可能构成环,虽然路走长了,但路费便宜了,这个问题要考虑到.还有就是剪枝啦:如果当前求得的路费比以前求得的答案要大,那就要回溯. mincost 明明

CSU-ACM2014暑假集训基础组训练赛(1) 解题报告

•Problem A HDU 4450                 水题,签到题 水题..没啥好说的.给大家签到用的. 1 #include <cstdio> 2 int main(){ 3 int n,a,ans; 4 while(scanf("%d",&n),n){ 5 ans = 0; 6 for(int i = 0;i < n;i++){ 7 scanf("%d",&a); 8 ans += a*a; 9 } 10 pr

CSU-ACM暑假集训基础组训练赛(4)解题报告

•Problem A SPOJ SUB_PROB   AC自动机 •题意: 给定一个长为M(M≤100000 )的文本串,和N(N≤1000)个长度不超过2000的模式串,问每个模式串是否在文本串中出现过? •几乎和周一课件上的第一个例题一模一样.. •把文本串丢到AC自动机里面去跑. •注意: •1.可能有两个相同的模式串(略坑吧.) •2.一个模式串可能是另一个模式串的后缀,即如果一个点的fail指针指向的点是一个“危险节点”,那么它本身也是一个“危险节点”. 1 #include <ios

「csp校内训练 2019-10-24」解题报告

「csp校内训练 2019-10-24」解题报告 T1.猴猴吃苹果 \(Description\) 猴猴最喜欢在树上玩耍,一天猴猴又跳上了一棵树,这棵树有 \(N \ (N \leq 50000)\) 个苹果,每个苹果有一个编号,分别为 \(0\) ~ \(N - 1\) 它们之间由 \(N-1\) 个树枝相连,猴猴可以从树枝的一端爬到树枝的另一端,所以猴猴可以从任意一个苹果的位置出发爬到任意猴猴想去的苹果的位置. 猴猴开始在编号为 \(K \ (K < N)\) 的苹果的位置,并且把这个苹果吃

「csp校内训练 2019-10-30」解题报告

「csp校内训练 2019-10-30」解题报告 T1.树 题目链接(逃) \(Description\): 现在有一棵树,共 \(N\) 个节点. 规定:根节点为 \(1\) 号节点,且每个节点有一个点权. 现在,有 \(M\) 个操作需要在树上完成,每次操作为下列三种之一: \(1 \ x \ a\):操作 \(1\),将节点 \(x\) 点权增加 \(a\). \(2 \ x \ a\):操作 \(2\),将以节点 \(x\) 为根的子树中所有点的权值增加 \(a\). \(3 \ x\)