zznu组队赛⑧

论如何优雅地暴力?

Problem A:

题意:ZCC在玩一个游戏, 在这个游戏中他有一个技能,可以把一张牌变成他想要的样子. 现在给出5张牌,问ZCC至少需要多少次可以把5张牌变成同花顺. (A,B,C,D分别表示4种花色的牌,每种花色有1,2,3,4....13), 同花顺首先花色必须相同,然后花色后面的数字必须依次递增

比如1,2,3,4,5   10,11,12,13,1 都被看成顺子,而11,12,13,1,2 则不是.

没什么技巧, 暴力枚举

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<queue>
#include<algorithm>
#include<cmath>
#include<iostream>
using namespace std;
typedef long long LL;
#define oo 1000000007
#define mod 1000000007
#define maxn 205
int maps[maxn][maxn];
void get(char s[])
{
    int x = s[0]-'A'+1;
    int y = 0;
    for(int i = 1; s[i]; i++)
        y = y*10+s[i]-'0';
    maps[x][y] = 1;
}
//maps[i][j](1<=i<=4 && 1<=j<=13) i表示花色 
int main()
{
   char s[maxn];
   int T, i, j, n, ans, sum;
   scanf("%d", &T);
   while(T--)
   {
       ans = 100;
       n = 5;
       memset(maps, 0, sizeof(maps));
       for(i = 1;i <= 5; i++)
       {
           scanf("%s", s);
           get(s); //标记该花色的牌 
       }
       for(i = 1;  i<= 4; i++)//枚举花色 
       {
           for(j = 1; j <= 10; j++)//枚举顺子起始位置 
           {
               int t = j, cnt=0, sum=0;
               while(cnt < 5)
               {
                   if(t > 13) t %= 13;
                   if(maps[i][t]==0) sum++;
                   cnt++;
                   t++;
               }

               ans = min(ans, sum);
           }
       }
       printf("%d
", ans);
   }
   return 0;
}

 Problem C:

  硬币兑换,由递推的感觉.

  首先考虑全部兑换成一种硬币的情况 1分的有1种  2分的有n/2种 3分的有n/3种,   然后考虑3种硬币混合的情况,枚举要兑换3分的个数相加即可. 如果兑换i(1<=i<=n/3)个3分的 那么就可以兑换2分的硬币(n-3*i)/2个,余下的补上一分的即可.

 int i, n, ans, k;
    while(scanf("%d", &n) != EOF)
    {

        k = n/3;
        ans = 1+n/3+n/2;//全部由一种硬币组成的情况 
        for(i = 1; i <= k; i++)//有i个3分硬币,余下的兑换成2分的,不足的用一分的补齐. 
            ans += (n-3*i)/2;
        printf("%d
", ans);
    }

  Problem D:

   n个人坐成一圈,每个人手中有一定数量的糖果(糖果数量为偶数),现在做一个游戏,每当老师吹一次哨,左边的人把手中的糖的一半分给他右边的人, 如果某个人手中的糖果是奇数个的话,老师就再分给他一个糖果,

问经过多少次吹哨,所有人手中的糖果数量都相同.输出吹哨的次数,以及最后每个人手中的糖果的数量. 题目貌似没有太清晰的数据范围,不过这道题暴力可以过. 代码略丑,大家凑合着看吧

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<queue>
#include<algorithm>
#include<cmath>
#include<iostream>
using namespace std;
typedef long long LL;
#define oo 1000000007
#define mod 1000000007
#define maxn 205

int candys[1005], n;
int judge()
{
    int i;
    for(i = 1; i < n; i++)
        if(candys[i] != candys[i-1]) return 0;
    return candys[0];
}
int main()
{
    int i, t, ans, s, last;
    while(scanf("%d", &n), n)
    {
        ans = s = 0;
        for(i=0; i < n; i++)
            scanf("%d", &candys[i]);

        while(!ans)
        {
            s++;
            last = candys[0];
            for(i = 1; i < n; i++)
            {
                t = candys[i];
                candys[i] = t/2 + last/2;
                if(candys[i]%2) candys[i]++;
                last = t;
            }
            candys[0] = candys[0]/2+last/2;
            if(candys[0]%2) candys[0]++;
            ans = judge();
            if(ans != 0) break;
        }
       printf("%d %d
", s, ans);
    }
    return 0;
}

  Problem E:

    这道题就是本次题目的坑点所在了, 关于题意就是判断一个数是否在给定的区间之内, A掉本题是需要脑洞的, 也是佩服出题人 ,真心不容易,,,

   题意就不过多描述了,详细看代码 

  坑点:比如 空串, 再比如只包含'-'的串? 再比如 -0? 等等等等,,就不一一枚举了.

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<queue>
#include<algorithm>
#include<cmath>
#include<iostream>
using namespace std;
typedef long long LL;
#define oo 1000000007
#define mod 1000000007
#define maxn 205
char s[maxn];
int judge(int mark)
{//mark 标记是否有 '-' 0表示没有,1表示有
    int i =0, j, len=strlen(s);

    if(mark == 1) i ++;

    if(mark && len==1) return 0; //只由一个负号非法

    if(s[i] == '0') return 0;//有前导0 非法

    if(len == 0 || len > 15) return 0;//字符串为空串或者长度太长 非法

    for(j = i; s[j]; j++)
    {
        if(s[j] >= '0' && s[j] <= '9')
            continue;
        return 0; //包含非数字字符 非法
    }

    return 1;
}
int main()
{
    int i, mark, legal, ok, a, b;
    LL suk;//计算合法的串的结果
    while(gets(s) != 0)
    {

        scanf("%d %d%*c", &a, &b);
        ok = suk = mark = legal = 0;

        if(s[0] == '-') mark = 1;

        legal = judge(mark);//1 表示合法,0表示非法

        if(legal)//合法的字符串参与 计算
        {
            i = 0;
            if(mark) i = 1;
            for(; s[i]; i++)
                suk = suk*10+s[i]-'0';
            if(mark) suk *= -1;
            if(suk >= a && suk <= b) ok = 1;
        }

        int len = strlen(s);
        if (len == 1 && s[0] == '0' && 0 >= a && 0 <= b) ok = 1;//只有1个0的情况也属合法的
        if(ok) puts("YES");
        else puts("NO");
    }
    return 0;
}

 Problem F:题意:YJC 买了个表但是他不会读  他会给你一个时针与分针的角度(这个角度是乘12000之后的角度)并且他不想时间太精确秒数以10计数算出这个角度可能的时间点(时间 from 00:00:00 to 11:59:59)

时针每分钟转1/2度 -- 每秒钟转1/120度  

分针每分钟转6度 每秒钟转1/10度

在给定时间 h m s 下 将 时针 分针 秒针所转动的角数同时扩大12000倍则
 
时针转的角度 == (h*3600+m*60+s)/120*12000;
 
分针转的角度 == (m*60+s)/10*12000;
转一圈的角度是360*12000,  
const int Round = 360*12000;
int main()
{
    int i, j, k, h, m, s, n;
    while(scanf("%d", &n)!=EOF)
    {

        for(i = 0; i < 12; i++)
        {
            for(j = 0; j < 60; j++)
            {
                for(k = 0; k < 60; k+= 10)
                {
                  h = (i*3600+j*60+k)*100;
                  m = (j*60+k)*1200;
                  s = abs(h-m);//计算角度差
                  if(s > Round/2) s = Round-s; //时针与分针的角度定义为较小的夹角
                  if(s == n)
                        printf("%02d:%02d:%02d
", i, j, k);
                }
            }
        }
    }
    return 0;
}

  Problem G:

有一个n*n的地图, 这个图是在水上飘着的?(不要问为什么,) 你可以在地图上的某一个具体位置放上一些 石头? 然后这个位置就成陆地了? (英语较渣,不过大致就是这个意思,能做题,) 现在问你能不能将一个地图分割成k块陆地, (对于一块陆地的定义,地图的某个位置如果放有石头, 以及其上下左右四个方向上所有连通的是石头的格子 构成一块陆地,  即不同块的陆地之间必须有水隔着). 如果可以分割,输出任意一种方案即可. 

解决方法:暴力枚举, 给地图的格子标号为 对应的行与列的和 即 i+j 如果是偶数 就放上一块石头, 观察是否放够k个(注意k==0的情况).(L代表石头, R代表是水) 

/*例如:
LL    LL
LL    RL  这2个2*2的图 只包含一块陆地
LR
RL   这2个2*2的图包含了2块陆地
*/
#include<cstdio>
#include<cstring>
#include<stack>
#include<queue>
#include<cmath>
#include<cstdlib>
#include<iostream>
#include<algorithm>
using namespace std;
const int oo = 1e9+7;
const int maxn = 1e6+1e5;
typedef long long LL;
int maps[105][105];
int main()
{
    int n, k, cnt, i, j, ok;
    while(scanf("%d %d", &n, &k) != EOF)
    {
        cnt = k;
        ok = 0;
        if(k==0) ok = 1;
        memset(maps, 0, sizeof(maps));
        for(i = 0; i < n && !ok; i++)
        {
            for(j = 0; j < n && !ok; j++)
            {
              if((i+j)%2==0)
              {
                  cnt--;
                  maps[i][j] = 1;
                  if(cnt == 0)
                  {
                      ok = 1;
                      break;
                  }
              }
            }
        }
        if(ok)
        {
            puts("YES");
            for(i = 0; i < n; i++)
            {
                for(j = 0; j < n; j++)
                {
                    if(maps[i][j]) printf("L");
                    else printf("S");
                }
                puts("");
            }
        }
        else puts("NO");
    }
    return 0;
}

  

  

原文地址:https://www.cnblogs.com/PersistFaith/p/5392293.html