组队赛——NO.1 (Accepted)

1、N-th Largest Value

题目链接

题意:找出倒数第三大数字

CODE:

#include <iostream>
#include <cstdio>
#include <cmath>
#include <cstring>
#include <cstdlib>
#include <algorithm>
#include <queue>
using namespace std;

typedef long long LL;

int main()
{
    ios::sync_with_stdio(false);

    int t,n,nn;
    int a[1000+10];

    cin>>t;

    while(t--)
    {
        cin>>nn;

        for(int i=0;i<10;i++)
            cin>>a[i];

        sort(a,a+10);

        cout<<nn<<' '<<a[7]<<endl;

    }
}

2、Equal Sum Partitions

题目链接

题意:输入 n个数字,可以分成1或多个连续数字组成的集合,要求这些集合的和相等,输出这个相等的和

例如:2 5 1 3 3 7  可以分成三个集合 (2,5) (1,3,3)(7)  每一个集合的和都是 7

思路:遍历n个数的和,当遍历到某一个数时,如果满足 几个集合的和等于该数,就输出这一个数字

CODE:

#include <iostream>
#include <cstdio>
#include <cmath>
#include <cstring>
#include <cstdlib>
#include <algorithm>
#include <queue>
using namespace std;

typedef long long LL;

int m;
 int a[10000+10];

int judge(int x)
{
    int sum=0;

    for(int i=0;i<m;i++)
    {
        sum+=a[i];

        if(sum==x)
            sum=0;

        else if(sum>x)  // 大于肯定不符合题意
            return 0;
    }

    if(sum!=0)   // 最后几个数的和不是 x,说明不符合题意
        return 0;
    return 1;
}

int main()
{
    ios::sync_with_stdio(false);

    int t,n;



    int ans=0,sum1=0;

    int flag=0;

    cin>>t;

    while(t--)
    {
        flag=0;
        sum1=0;
        ans=0;

        cin>>n>>m;

        for(int i=0;i<m;i++)
        {
            cin>>a[i];
            sum1+=a[i];
        }

        for(int i=1;i<=sum1;i++)
        {
            if(judge(i)==1)
            {
                ans=i;
                break;
            }
        }

            cout<<n<<' '<<ans<<endl;
    }

}

3、Running Median

题目链接

题意:

给定 n(奇数)个数,求【1,2*i+1】(1<= i <= n / 2)的中位数

对 【1,2*i+1】 进行 sort 排序,求出中位数

需要注意一下格式,控制一下输出个数,每10个换一行,当最后输出的几个不足10个时,同时需要换行

CODE:

#include <iostream>
#include <cstdio>
#include <cmath>
#include <cstring>
#include <cstdlib>
#include <algorithm>
#include <queue>
using namespace std;

typedef long long LL;

int main()
{
    LL t,n,m,x,y;

    LL a[10000+10];
    LL ans[10000];
    LL flag=0;
    LL sum=0;

    scanf("%lld",&t);
    LL d=0;
    while(t--)
    {
        scanf("%lld %lld",&n,&m);
        d=0;
        for(LL i=1; i<=m; i++)
        {
            scanf("%lld",&a[i]);
            if(i%2!=0)
            {


                sort(a+1,a+i+1);
                ans[++d]=a[i/2+1];
            }
        }

        printf("%lld %lld\n",n,m/2+1);

        LL b=0;
        if(d==10)
        {

            for(LL i=1; i<=d; i++)
            {

                if((i-1)%10==0)
                    printf("%lld",ans[i]);
                else
                    printf(" %lld",ans[i]);
            }

                printf("\n");

        }
        else
        {
            for(LL i=1; i<=d; i++)
            {
                b++;
                if((i-1)%10==0)
                    printf("%lld",ans[i]);
                else
                    printf(" %lld",ans[i]);
                if(b%10==0&&b!=d)
                    printf("\n");
            }

                printf("\n");
        }


    }

}

4、The Next Permutation

题目链接

题意:输出下一个全排列,如果没有下一个,输出“BIGGEST”;

思路:利用函数 next_permutation(s,s+n);  //  求下一个全排列函数
 

#include <iostream>
#include <cstdio>
#include <cmath>
#include <cstring>
#include <cstdlib>
#include <algorithm>
#include <queue>
using namespace std;

typedef long long LL;
#define memset(a,n) memset(a,n,sizeof(n))

int main()
{
    int t,cnt;
    char s[100];

    char c[100];

    int flag=0;

    cin>>t;

    while(t--)
    {
        flag=0;

        cin>>cnt>>s;

        strcpy(c,s);

        do
        {
            if(strcmp(s,c)>0)
            {
                printf("%d %s\n",cnt,s);
                flag=1;
                break;
            }

        }while(next_permutation(s,s+strlen(s)));

        if(flag==0)
        {
            printf("%d ",cnt);
            printf("BIGGEST\n");
        }
    }
}

5、Balls

题目链接

题意:
给你 n个鸡蛋m个球,鸡蛋的硬度定义为:如果鸡蛋从第 i 层上掉下来没有破裂,而从第 i+1 层上掉下来就破裂了,那么这个鸡蛋的硬度就是 i, 求在最坏情况下我们最少需要做多少次实验思路

思路:动态规划 dp[i][j] // i层j个鸡蛋,在最坏情况下需要做的最少实验

分析:
从第 i 层扔下,如果碎了,还剩 m−1 个鸡蛋,为确定下面楼层中的安全位置,还需要dp[i−1,m−1] 次(子问题);

不碎的话,上面还有 n−i 层,还需要 dp[n−i,m]次;求两者最大的一个(保证最坏情况),再去求一个整体的最少次数

状态转移方程 dp[i][j] = min(dp[i][j],max(dp[i-1][k-1],dp[i][j-k])+1); // k 为当前楼层数,加1是因为碎了的话已经扔了一次

注意初始化,当0层的时候,不论多少个鸡蛋,最少的次数就是 0

CODE:

#include <iostream>
#include <cstdio>
#include <cmath>
#include <cstring>
#include <cstdlib>
#include <algorithm>
#include <queue>
using namespace std;

typedef long long LL;
#define memset(a,n) memset(a,n,sizeof(n))
#define INF 0x3f3f3f3f

int dp[1010][60];

int main()
{
    int t,m,b,cnt;

    cin>>t;

    for(int i=0; i<1002; i++)
        for(int j=0; j<51; j++)
            dp[i][j]=INF;

    for(int i=0;i<=50;i++)
        dp[0][i]=0;

    for(int i=1;i<=1000;i++)
            for(int j=1;j<=50;j++)
                for(int k=1;k<=i;k++)
                    dp[i][j]=min(dp[i][j],max(dp[i-k][j],dp[k-1][j-1])+1);

    while(t--)
    {
        cin>>cnt>>b>>m;

        cout<<cnt<<' '<<dp[m][b]<<endl;


    }
}

6、Adjacent Bit Counts

题目链接

题意:
给n位数,m是和,求由 0、 1 组成的长度是 n,相邻两位数乘积之和等于 m的方法数

思路:动态规划
用三维数组,dp[i][j][x]  //  i 代表的是长度,j 代表的是和,x代表末尾数是0 还是 1 

状态转移方程:
如果末尾数为 0的话,dp[i][j][0] = dp[i-1][j][0] + dp[i-1][j][1]; 

            // 末尾是0,那么前一位不论是 0还是1,与0相乘都不影响结果
如果末尾数为 1的话,dp[i][j][1] = dp[i-1][j][0] + dp[i-1][j-1][1];
      // 末尾是1,那么前一位末尾是0不影响结果,如果前一位结果是1,和加1

CODE:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <cstdlib>
#include <algorithm>
using namespace std;

typedef long long LL;
#define memset(a,n) memset(a,n,sizeof(a))

int dp[110][110][3];

int main()
{
    int t,n,k;
    int cnt;
    memset(dp,0);

    dp[1][0][1]=1;
    dp[1][0][0]=1;

    for(LL i=2;i<105;i++)
    {
        for(LL j=0;j<105;j++)
        {
            for(LL l=0;l<2;l++)
            {
                if(l==0)
                    dp[i][j][l]=dp[i-1][j][0]+dp[i-1][j][1];
                else
                    dp[i][j][l]=dp[i-1][j][0]+dp[i-1][j-1][1];
            }
        }
    }

    scanf("%d",&t);

    while(t--)
    {
        scanf("%d %d %d",&cnt,&n,&k);
        LL ans;
        ans=dp[n][k][0]+dp[n][k][1];
        printf("%d %d\n",cnt,ans);
    }

}

猜你喜欢

转载自blog.csdn.net/JKdd123456/article/details/83543275