12.26总结

题目描述

给定一个长度为n的序列a,并且序列a中的元素只由1或0构成
你可以执行一种操作,选定序列a中的一个元素a[i],使得a[i]=1-a[i]
最后你可以得到一个x和一个y
    x:序列a中连续1的最长序列长度
    y:操作次数
要求你求出最大的x-y

输入

第一行给定一个t(1<=t<=1e3),表示有t组样例
对于每一组样例,总共有两行
第一行给定一个n(1<=n<=1e5),表示序列a的长度
第二行给定n个元素,表示序列a

输出

最大的x-y

思路:把0转变成1,y就会加1,同时x也会加1,所以只需要n-0的个数即可。

 

#include<stdio.h>

int main()
{
    int t;
    scanf("%d",&t);
    while(t--)
    {
        int n,i,t=0;
        scanf("%d",&n);
        int a[n];
        for(i=0;i<n;i++)
            scanf("%d",&a[i]);
            for(i=0;i<n;i++)
            {
                if(a[i]==0)
                    t++;
            }
            printf("%d\n",n-t);
    }
}

题目描述

给定一个递推式a[i]=a[i-1]/2(i>1,向下取整),并且给定a[1],要求你按照从小到大的顺序输出所有的a[i](a[i]!=0)

输入

多组输入(不超过1e3组)
对于每一组输入给定一个a[1](1<=a[1]<=1e18)

输出

根据题目要求,求出通过递推式计算出的数组a,并按照从小到大的顺序输出所有的a[i](a[i]>0)

可以用递归,简洁明了。

#include<stdio.h>
void fun(long long x)
{
    if(x==0)
        return ;
    fun(x/2);
    printf("%lld ",x);
}
int main()
{
    long long int t;
    while(scanf("%lld",&t)!=EOF)
    {
        fun(t);
        printf("\n");
    }
}

题目描述

萝卜上次已经说过要给各位同学出一道冒泡排序,那么此题就以冒泡排序为主吧,可是实验室的学长学姐觉得学弟学妹们都很厉害,所以就加了各种各样的条件,最 终萝卜还是选择加一些条件,比如:让你直接排序输出结果就体现不出冒泡排序了。所以萝卜决定必须要用冒泡排序才能做出来的题目才叫冒泡排序的题目嘛?所以 这里只需要你在使用冒泡排序的时候统计交换的次数,在定义一个规则,如果存在相同的数,那么出现较早的那个数就排在后面。请帮萝卜解决这个问题吧。

输入

只有一组数据。

第一行一个n。(n<100)

接下来有n个数,表示要排序的数(不超过100)。

输出

输出交换的次数。

思路:不同元素之间交换可以之间统计,但是相同元素不一样。两个相同元素只需要交换1次,但是三个要交换2+1次,四个要交换3+2+1次,所以最好把相同元素拿出来判断

#include<stdio.h>

int main()
{
    int n,i,j,k=0,t,q;
    scanf("%d",&n);
    int a[100];
    for(i=0;i<n;i++)
        scanf("%d",&a[i]);
    for(i=0;i<n-1;i++)
        for(j=0;j<n-1-i;j++)
        if(a[j]>a[j+1])
    {
        k++;
        t=a[j];a[j]=a[j+1];a[j+1]=t;
    }
    j=0;
    while(j!=n-1)
        {
            for(q=1; j<n-1; j++)
                if(a[j]==a[j+1])
                    q++;
                else
                {
                    j++;
                    break;
                }
            while(q--)
                k=k+q;
        }
    printf("%d\n",k);
}

题目描述

实验室的学长学姐要去聚餐,聚餐就要喝酒,可是偏偏大家的酒量都不行,喝一杯就醉。现在大家一起玩个游戏,桌上围坐着2n个人。其中n个人是学长,另外n 个人是学姐。如果从第一个人开始数数,数到第m个人,则让他喝一杯酒,然后他就醉了;然后从喝醉的人之后开始数数,再让数到的第m个人喝酒……依此方法不 断让围坐在桌上的人喝酒。不过,问题来了,学长可以喝醉,但是学姐不能喝醉,所以预先应如何安排这些学长与学姐的座位,能使得在让n个人喝醉之后,桌上围 坐的没醉的n个人全是学姐。

输入

多组数据,每组数据输入:学长和学姐的人数分别为n(n<=3000)、以及m表示数到第m个人就倒下(m<=1000);

输出

对于每一组数据,输出2n个大写字母,‘G’表示学姐,‘B’表示学长,50个字母为一行,不允许出现空白字符。每组测试数据后输出一个空行。

样例输入

2 3
2 4

样例输出

GBBG

BGGB 

#include<stdio.h>
 
int main()
{
    int n,m;
    while(scanf("%d %d",&n,&m)!=EOF)
    {
        int a[6000],i,k=0,t=0;
        for(i=1;i<=2*n;i++)
            a[i]=1;
            for(i=1;i<=2*n;i++)
        {
            if(a[i]==1)
            {
                k++;
            if(k==m)
            {
                a[i]=0;k=0;t++;
            }
            }
            if(t==n)
                break;
            if(i==2*n)
                i=0;
        }
        for(i=1;i<=2*n;i++)
        {
            if(a[i]==1)
                printf("G");
            else
                printf("B");
                if(i%50==0)
                    printf("\n");
        }
        printf("\n\n");
    }
}

题目描述

由于近期的降雨,雨水汇集在农民约翰的田地不同的地方。我们用一个 N\times M(1\leq N\leq 100, 1\leq M\leq 100)N×M(1≤N≤100,1≤M≤100) 的网格图表示。每个网格中有水(W) 或是旱地(.)。一个网格与其周围的八个网格相连,而一组相连的网格视为一个水坑。约翰想弄清楚他的田地已经形成了多少水坑。给出约翰田地的示意图,确定当中有多少水坑。

输入第 11 行:两个空格隔开的整数:NN 和 MM。

第 22 行到第 N+1N+1 行:每行 MM 个字符,每个字符是 W 或 .,它们表示网格图中的一排。字符之间没有空格。

输出一行,表示水坑的数量。

输入输出样例

10 12
W........WW.
.WWW.....WWW
....WW...WW.
.........WW.
.........W..
..W......W..
.W.W.....WW.
W.W.W.....W.
.W.W......W.
..W.......W.

输出样例

3

思路:需要运用深度优先搜索,从任意'W'开始,都把相邻的'W'区域用'.'代替。一次dfs后就有一块水坑被替换为’.',所以统计dfs的次数,就是水坑的数量。在输入时不要一个一个输入,否则会出现问题,导致最后结果错误。

​
#include<stdio.h>
int N,M;
char field[105][105];
void dfs(int x,int y)
{
    field[x][y]='.';//将所有'W'替换为'.'
    for(int dx=-1;dx<=1;dx++)
    {
        for(int dy=-1;dy<=1;dy++)//循环历经8个方向,向x方向移动dx,y方向移动dy,移动结果为(nx,ny)
        {
            int nx=x+dx,ny=y+dy;
            if(0<=nx&&nx<N&&0<=ny&&ny<M&&field[nx][ny]=='W')//判断是否在园子内,是否有水
                dfs(nx,ny);
        }
    }
    return ;
}
void solve(int N,int M)
{
    int res=0;
    for(int i=0;i<N;i++)
    {
        for(int j=0;j<M;j++)
        {
            if(field[i][j]=='W')
            {
                res++;
                dfs(i,j);
            }
        }
    }
    printf("%d\n",res);
}
int main()
{
    scanf("%d %d",&N,&M);
    int i,j;
    for(i=0;i<N;i++)
        scanf("%s",&field[i]);
    solve(N,M);
}

​

题目描述

CC喜欢下棋, 她有一天去商店发现有很多很奇怪的棋盘,那些棋盘的长宽不一样,宽永远是2,然后长有从1-n等等
然后那个商店还卖很奇怪的棋子,都是1*2的大小,CC突然有个想法,把棋子放到这棋盘上摆满有多少种方法

输入

输入数据由多行组成,每行包含一个整数n,表示该测试实例棋盘的规格是2×n (0<n<=50)。

输出

对于每个测试实例,请输出铺放方案的总数,每个实例的输出占一行。

思路:可以先例举前5个的范例找规律,分别为1,2,3,5,8……即a[n]=a[n-1]+a[n-2]。然而直接用递归时会时间超限,所以最好用数组进行记忆化搜索。

#include<stdio.h>

int main()
{
    long long int a[55]={0},i;
    a[1]=1;a[2]=2;
    for(i=3;i<=50;i++)
        a[i]=a[i-1]+a[i-2];
    int n;
    while(scanf("%d",&n)!=EOF)
    {
        printf("%lld\n",a[n]);
    }
}

题目描述

给定若干个整数,要求使用分治算法求出最大值和最小值。

输入

输入只包括若干个用例,每个用例占两行,第一行为整数个数n(1<=n<=100)。第二行为n个整数

输出

每个用例用一行输出其最小值和最大值,用空格隔开。

分治法:将一个规格为n的问题分解成k个规模较小的子问题,再把子问题合并求解

#include<stdio.h>
int max(int a[],int n)
{
    int max1=0,i;
    for(i=0;i<n;i++)
        if(a[i]>a[max1])
        max1=i;
    return a[max1];
}
int min(int a[],int n)
{
    int min1=0,i;
    for(i=0;i<n;i++)
        if(a[i]<a[min1])
        min1=i;
    return a[min1];
}
int main()
{
    int t;
    scanf("%d",&t);
    while(t--)
    {
        int n,a[105],b[105],c[105],maxx[2],minn[2],i,j,t,s;
        scanf("%d",&n);
        for(i=0;i<n;i++)
         scanf("%d",&a[i]);
        t=n/2;s=n-t;
        for(i=0;i<t;i++)
            b[i]=a[i];
        for(j=0;j<s;j++)
            c[j]=a[i++];
        maxx[0]=max(b,t);maxx[1]=max(c,s);
        minn[0]=min(b,t);minn[1]=min(c,s);
        printf("%d %d\n",min(minn,2),max(maxx,2));
    }
}

题目描述

Edmondsiu用沙袋练习武术。Edmondsiu希望把沙袋摆在他家豪宅里面。Edmondsiu的豪宅有一个由1*1的地砖铺成的1*n的院子里。Edmondsiu是处女座的,所以他要把一个沙袋正好摆在一个地砖上,并且两个沙袋之间地砖必须大于等于两个,现在Edmondsiu想知道在至少摆放一个沙袋的情况下,有多少种摆法。

输入

输入有多组数据,每组数据第一行为一个整数n(1 < = n < = 60)

输出

对于每组数据输出一行表示摆放方案数

思路:在分析前四项时,简单粗暴认为递推公式是a[n]=a[n-1]+a[n-2],但是多分析一个例子就会发现错误,应该是a[n]=a[n-1]+a[n-3]+1。同样,用递归还是会超限,要用记忆化搜索。

#include<stdio.h>

int main()
{
    long long int a[65],i;
    a[1]=1;a[2]=2;a[3]=3;
    for(i=4;i<=60;i++)
        a[i]=a[i-1]+a[i-3]+1;
    int n;
    while(scanf("%d",&n)!=EOF)
    {
        printf("%lld\n",a[n]);
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值