【Low版】HAUT OJ Contest1035 2017届新生周赛(六)题解

问题 A: 比赛

时间限制: 2 秒 内存限制: 256 MB | 提交: 393 解决: 98
提交 状态

题目描述

学校要派6名同学组成两个队(一个队3个人)去参加比赛,每个同学有一个分数,学校希望两个队的分数相等,每个队的分数为该队所有队员的分数的总和。

你的任务是判断是否可能组成两个队使两个队的分数相等。

输入

第一行:整数T,测试实例个数。

对于每组测试实例:

输入一行:包含6个整数a1, ..., a6 (0 ≤ ai ≤ 1000) ,代表每个同学的分数

输出

每组测试实例输出一行:如果可能组成两个队使两个队的分数相等,则输出"YES";否则输出"NO"。

样例输入

2
1 3 2 1 2 1
1 1 1 1 1 99

样例输出

YES
NO

//我的思路就是直接暴力for循环打表生成所有的有顺序的组合数列,其实这也可以作为一道深
搜入门基础题目!《啊哈算法》上有原题及形象的代码!

#include<stdio.h>     //A
#include<iostream>
#include<algorithm>
#include<string.h>
#include<math.h>
#include<stdlib.h>
using namespace std;
#define ll long long
#define N 200
int a[800][10];
int main()
{
    int i,T,i1,i2,i3,i4,i5,i6;
    int m,n,cnt,flag;
    scanf("%d",&T);
    while(T--)
    {
        cnt=0;flag=0;
        for(i=1;i<=6;i++)
            scanf("%d",&a[0][i]);
        for(i1=1;i1<=6;i1++){
            for(i2=1;i2<=6;i2++){
                    if(i2==i1)continue;
                for(i3=1;i3<=6;i3++){
                    if(i3==i1||i3==i2)continue;
                    for(i4=1;i4<=6;i4++){
                        if(i4==i1||i4==i2||i4==i3)continue;
                        for(i5=1;i5<=6;i5++){
                            if(i5==i1||i5==i2||i5==i3||i5==i4)continue;
                            for(i6=1;i6<=6;i6++){
                                if(i6==i1||i6==i2||i6==i3||i6==i4||i6==i5)
                                    continue;
                                else
                                {
                                    ++cnt;
                                    a[cnt][1]=a[0][i1];a[cnt][2]=a[0][i2];a[cnt][3]=a[0][i3];
                                    a[cnt][4]=a[0][i4];a[cnt][5]=a[0][i5];a[cnt][6]=a[0][i6];
                                }
                            }
                        }
                    }
                }
            }

        }
        for(i=1;i<=cnt;i++)
        {
            if(a[i][1]+a[i][2]+a[i][3]==a[i][4]+a[i][5]+a[i][6]){
                flag=1;
                break;
            }
        }
        if(flag)
            printf("YES\n");
        else
            printf("NO\n");
    }


    return 0;
}
View Code

//其实不然

#include<stdio.h>   //A题
#define N 10
int main()
{
    int n,a[N],i;
    scanf("%d",&n);
    while(n--)
    {
        for(i=1;i<=6;i++)
            scanf("%d",&a[i]);
           if(a[1]+a[2]+a[3]==a[4]+a[5]+a[6]||a[1]+a[2]+a[4]

==a[3]+a[5]+a[6]||a[1]+a[2]+a[5]==a[4]+a[3]+a[6]||a[1]+a[2]+a[6]==a

[4]+a[5]+a[3]||a[1]+a[4]+a[3]==a[2]+a[5]+a[6]||a[1]+a[5]+a[3]==a

[4]+a[2]+a[6]||a[1]+a[6]+a[3]==a[4]+a[5]+a[2]||a[1]+a[4]+a[5]==a

[6]+a[2]+a[3]||a[1]+a[4]+a[6]==a[5]+a[2]+a[3]||a[1]+a[5]+a[6]==a

[4]+a[2]+a[3])
            printf("YES\n");
        else
            printf("NO\n");
        
    }
    return  0;
}
View Code

//没错上面的代码也可以,一共10种情况;分成的两组数中每组数不要求顺序,故
每次枚举一半就可以了!(自己动手画画)

---------------------------------------------------------

问题 B: 消灭怪物

时间限制: 2 秒 内存限制: 256 MB | 提交: 125 解决: 36
提交 状态

题目描述

有水平放置的编号从1到n的n个格子,每个格子中有一个或者多个怪物。你可以在任何一个格子里投下炸弹,这个格子里的怪物都将受到伤害,当每个怪物第一次受到伤害,它会立即移动到相邻的格子(格子n内的怪物只能移动到格子n-1,格子1内的怪物只能移动到格子2),当一个怪物受到两次伤害时,他将彻底被消灭。怪物只有在第一次受到伤害时才一移动,它们自己不会移动。

你要找出消灭所有怪物所需要的最小炸弹数。

输入

第一行:整数T,表示测试实例个数。

对于每组测试实例:

输入一个整数n (2 ≤ n ≤ 100 000) ——表示有n个格子。

输出

每组测试实例输出一行:包括一个整数——消灭所有怪物所需要的最小炸弹数。

样例输入

2
2
3

样例输出

3
4

#include<stdio.h>
#include<iostream>    //问题 E: QAQ
#include<algorithm>
#include<string.h>
#include<math.h>
#include<stdlib.h>
using namespace std;
#define ll long long
#define N 200
char a[108];

int main()
{
    int T,i,j,k,len,cnt;
    scanf("%d",&T);
    while(T--)
    {
        cnt=0;
        scanf("%s",a);
        len=strlen(a);
        for(i=0; i<len; i++)
        {
            for(j=i+1; j<len; j++)
            {
                for(k=j+1; k<len; k++)
                {
                    if(a[i]=='Q'&&a[j]=='A'&&a[k]=='Q')
                    {
                        cnt++;
                    }
                }
            }
        }
        printf("%d\n",cnt);
    }

    return 0;
}
View Code

//三重FOR循环分别代表三个指针进行遍历,轻松解决问题!

问题 D: 最小的数

时间限制: 1 秒 内存限制: 256 MB | 提交: 192 解决: 29
提交 状态

题目描述

给你两个一维数组(都为大于等于1且小于等于9的数),从第一个数组中取至少一个数字,再从第二个数组中取至少一个数字,用你选取的数字组成一个整数,求能组成的最小整数。
如果从第一个数组中选取的数与从第二个数组中选取的数相等,只保留一个即可。

输入

第一行:一个整数T,表示测试实例个数
对于每组测试实例:

第一行:包含两个整数n 和 m (1 ≤ n, m ≤ 9) —— 分别表示两个数组的大小
第二行:包含n个整数a1, a2, ..., an (1 ≤ ai ≤ 9) ——第一个数组
第三行:包含m个整数 b1, b2, ..., bm (1 ≤ bi ≤ 9) 第二个数组

输出

每组测试实例输出一行:包含一个整数 —— 能组成的最小整数

样例输入

2
2 3
4 2
5 7 6
8 8
1 2 3 4 5 6 7 8
8 7 6 5 4 3 2 1

样例输出

25
1
#include<stdio.h>
#include<math.h>
#include<string.h>
#include<algorithm>
using namespace std;
#define INT 0x7fffffff
#define INF 0x3f3f3f3f
 
 
int main()
{
    int t, n, m, a[25], b[15];
    scanf("%d", &t);
    while(t--)
    {
        scanf("%d%d", &n, &m);
        for(int i=0; i<n; i++)
            scanf("%d", &a[i]);
        for(int i=0; i<m; i++)
            scanf("%d", &b[i]);
        sort(a,a+n);
        sort(b, b+m);
        int s=999;
        for(int i=0; i<n; i++)
        {
            for(int j=0; j<m; j++)
            {
                if(a[i]==b[j])
                    s=min(min(a[i], b[j]), s);
            }
        }
        if(s!=-1&&s!=999)
            printf("%d\n", s);
        else if(a[0]<b[0])
            printf("%d\n", a[0]*10+b[0]);
        else
            printf("%d\n", b[0]*10+a[0]);
    }
    return 0;
}
View Code

//这个程序用到了库函数sort排序,提供一组样例,数组a:1 2 9,数组b:3 4 9 ,按照题意该组数据的最小值为9,不应该为13!

#include<stdio.h>
#include<iostream>
#include<algorithm>
#include<string.h>
#include<math.h>
#include<stdlib.h>
using namespace std;
#define ll long long
#define N 200
int a[15],b[15];

int main()
{
    int T,n,m,i,j,minn1,minn2,ans;
    scanf("%d",&T);
    while(T--)
    {
        minn1=minn2=100;
        scanf("%d%d",&n,&m);
        for(i=1;i<=n;i++){
            scanf("%d",&a[i]);
            minn1=min(minn1,a[i]); //表示A数组的最小值
        }
        for(i=1;i<=m;i++){
            scanf("%d",&b[i]);
            minn2=min(minn2,b[i]);  //表示B数组的最小值
        }
        if(minn1==minn2)
            ans=minn1;
        else
            ans=min(minn1*10+minn2,minn1+minn2*10);
        for(i=1;i<=n;i++){
            for(j=1;j<=m;j++){
                if(a[i]==b[j]) //如果出现重复值就拿重复值跟ans比较
                {
                    if(ans>a[i])
                        ans=a[i];
                }
            }
        }
        printf("%d\n",ans);
    }

    return 0;
}
View Code

//上面这个代码用的是一般排序,有一点需要注意的是a数组的数跟b数组的数进行组合,a数组的最小数可以放前面,也可以放到后面去!

问题 F: 括号配对

时间限制: 1 秒 内存限制: 256 MB | 提交: 31 解决: 17
提交 状态

题目描述

给出一串长度为n的括号序列(只包含小括号),计算出最少的交换(两两交换)次数,使整个括号序列匹配。
我们认为一个括号匹配,即对任意一个')',在其左侧都有一个'('与它匹配,且他们形成一一映射关系。

输入

第一行:一个整数T,表示测试实例个数
对于每组测试实例:

第一行:整数n(0≤n≤5×10^6 ),表示括号序列长度
第二行:一个字符串,表示括号

输出

每组测试实例输出一行:包含一个整数 ,表示最少的交换次数

样例输入

2
6
(()))(
6
)))(((

样例输出

1
2
#include<stdio.h>
#include<math.h>
#include<string.h>
#include<algorithm>
using namespace std;
#define INT 0x7fffffff
#define INF 0x3f3f3f3f
 
char ch[5000006];
int main()
{
    int t, n, m;
 
    scanf("%d", &t);
    while(t--)
    {
        int s=0;
        scanf("%d", &n);
        scanf("%s", ch);
        for(int i=0; i<n; i++)
        {
            if(ch[i]=='(')
                s++;
            else
            {
                if(s>0)
                    s--;
            }
        }
        printf("%d\n", (s+1)/2);
    }
    return 0;
}
View Code

//找规律题



你不逼自己一把,你永远都不知道自己有多优秀!只有经历了一些事,你才会懂得好好珍惜眼前的时光!
原文地址:https://www.cnblogs.com/zhazhaacmer/p/7911178.html