12.18 20届第二次周测

12.18 20届第二次周测

b站题解:https://www.bilibili.com/video/BV1SK411u7aL

HDU 2002 计算球的体积

简单的基础运算,今日签到题。

#include<stdio.h>
#define PI 3.1415927

int main(){
    double r;
    while(~scanf("%lf",&r)){
        printf("%.3lf\n",4*PI*r*r*r/3);
    }
    return 0;
}

HDU 2081 手机短号

考察对字符数组的一个使用。`

#include<stdio.h>

char a[15];
int main(){
    int T;
    scanf("%d",&T);
    while(T--){
        scanf("%s",&a);
        printf("6");
        for(int i=6;i<11;i++)  printf("%c",a[i]);
        printf("\n");
        
    }
    return 0;
}

HDU 2042 不容易系列之二

类似与本学期大一c语言考试中猴吃桃问题。
题中告诉到达市场时剩3只羊,且之前每经过一个站被拿走一半再还一只。
那么我们从后往前推 那就是 上一站的羊数=(当前羊数-1)*2

#include<stdio.h>


int main(){
    int T;
    scanf("%d",&T);
    while(T--){
        int a;
        int res=3;
        scanf("%d",&a);
        while(a--){
            
            res=(res-1)*2;
            
        }
       
        printf("%d\n",res);
    }
    return 0;
}

HDU 2092 整数解

我想到两种方法:
1.暴力枚举,从-9999枚举到9999。(由于数据范围较小,所以可暴力)
2.将两个方程联立成一个一元二次方程,使用根的判别式进行求解。
第一个方法比较好写,那就写第一个把。

#include <stdio.h>

int main(){
    int s,m;
    int i;
    while(~scanf("%d%d",&s,&m)){
        if(s==0 && m==0){
            break;
        }
       
        for(i=-9999;i<=9999;i++){
            if(i*(s-i)==m){
                printf("Yes\n");
                break;
            }
        }
        if(i==10000){       //说明在上个for循环走走到尽头,没有被break,意味着无解
            printf("No\n");
        }
    }
    return 0;
}

HDU 2037 今年暑假不ac

考察了一个简单贪心问题。
再次科普下贪心是什么:在对问题求解时,总是作出在当前看来是最好的选择。也就是说,不从整体上加以考虑,它所作出的仅仅是在某种意义上的局部最优解(是否是全局最优,需要证明)。若要用贪心算法求解某问题的整体最优解,必须首先证明贪心思想在该问题的应用结果就是最优解

此题贪心思路为:我们讲所有节目按照结束时间排序,从小到大,那么我们再从头开始寻找下一个开始时间大于等于上一个结束时间。若满足则答案加一。循环操作。这样可获得这个问题的整体最优解。即看的最多完整节目数。

#include <stdio.h>
#include <algorithm>
#include <iostream>
using namespace std;

const int N=110;
typedef struct 
{
    int start; //节目开始时间
    int end;   //节目结束时间
}watch;//定义一个watch类型
watch p[N]; //一个watch类型 数组p
/*const int cmp( watch a, watch b)
{
    return a.end<b.end;
}*/
int main()
{
    int n;
    while(scanf("%d",&n),n)
    {
        
        for(int i=0;i<n;i++) scanf("%d%d",&p[i].start,&p[i].end);
        
        //sort(p,p+n,cmp); c++排序
        for (int j = 0; j < n; j++)  //适合现阶段大一的冒泡排序
	   {
		    for (int i = 0; i < n - 1 - j; i++)
		    if (p[i].end > p[i + 1].end)    //以节目结束时间排序 从小到大
		    {
			    swap(p[i],p[i+1]);
		    }
	    }

            int cnt=1;
            for(int i=0;i<n;i++)
            {
                for(int j=i+1;j<n;j++)
                    if(p[i].end<=p[j].start){ //寻找下一个开始时间大于等于上一个结束时间
                    i=j;
                    cnt++;
                }
            }
           printf("%d\n",cnt);
    }
    return 0;
}


HDU 2046 骨牌铺方格

n 张牌可以由 n - 1 张牌后面再加一张竖着放的牌得到,还可以由 n - 2 张牌后面再加两张牌得到。
(n - 2 张牌后面再加两张牌的情况只能是加两张横着放的,如果加两张竖着放的牌会和“ n - 1 张牌后面再加一张牌”的情况重复。)
n规模的格子只能从n-1和n-2得来,n-1的时候我们增加一个2×1格子,竖着放,可以有s(n-1)种放法,n-2时候我们可以增加2×2个格子,2个都横着放,可以有s(n-2)种方法

综上所述,此题为斐波那契数列模型

#include <stdio.h>

int main()
{
    int i, t;
    while(~scanf("%d", &t))
    {
        long long int s[60]; //长整型 (可能会爆int)
        s[0] = 1;
        s[1] = 2;
        for(i = 2; i < t; i++)
        {
            s[i] = s[i - 1] + s[i - 2];
        }
        printf("%lld\n",s[t - 1]);
    }
 
    return 0;
}

HDU 2050 折线割平面

该题为递推数学题;
图要自己去画,前面两条题目都已经给出了;
那么你把 n=3 的时候画出来就可以看到了,应该是被分成了16块;
n=4 的时候画出来可以看到,最多被分成了29块;
那么由 n=1 的时候分成了2块 ; n=2的时候分成了 7块 ,可以推出来:
f(2)-f(1)=5;
f(3)-f(2)=9;
9-5=4;
f(4)-f(3)=13;
13-9=4;
那么他们的加数的都是每次增加了 4;
可以推出 a(n)=5+4*(n-1); —> a(n)=4*n+1

所以可推出:f(n)=f(n-1)+4*(n-1)+1;
所以有递推公式:

f(n)=f(n-1)+4(n-1) + 1;

  =f(n-2)+4(n-2)+4(n-1)+2;

  .......

 =f(n-(n-1)) +4(n-(n-1))+4(n-(n-2))+......+4(n-1) + n-1;

=f(1) +4(1+2+3+4+....+n-1)+n-1;

=2+4((n-1)(n-1+1)/2)+n-1;

=2n^2-n+1;
#include <stdio.h>
typedef long long LL;
int main()
{
    int T,n;
    LL r;
    scanf("%d",&T);
    while(T--)
    {
        scanf("%d",&n);
        r = 2*n*n - n + 1;
        printf("%lld\n",r);
    }
    return 0;
}

HDU 2208 唉,可爱的小朋友

有m个小皮球和n个小朋友,小朋友是0~N-1号。
1.把每个小皮球看成一组,通过小皮球来进行递归遍历。
2.假设我们成功地把v号小朋友放进1号小皮球组,然后再进入一次dfs,把v+1号小朋友放进1号小皮球组,如果v+1号小朋友不能放进1号小皮球组,就把v+1号小朋友放进2号小皮球组,……,如果前面都失败了,就退回来,把v号小朋友放进2号小皮球组,直到如果找到了一个满足的方式,就返回true,否则如果所有情况都不成立,就返回false。

#include<stdio.h>
#include<string.h>
#define MAX 11
int n,m;
bool map[MAX][MAX];
int visited[MAX];//第i号小朋友进的组号 
bool check(int v,int tag)//第v号小朋友想进第tag组 
{
    for(int i=0;i<n;i++) 
        if(i!=v&&visited[i]==tag&&map[v][i]==false)//i号小朋友玩tag号球,但是i号小朋友不喜欢v号小朋友
            return false;    
    return true; 
}
bool dfs(int v)
{ 
    if(v>=n) //n个小朋友都有组了,递归结束,找到了可以找的答案 
        return true;
    else
    {
        for(int i=1;i<=m;i++)//选择每个皮球作为分组 
        {
            if(visited[v]==0&&check(v,i))//判断v号小朋友是否可以进i号皮球组 
            {
                visited[v]=i;//加入第i组 
                if(dfs(v+1))//看看后面的小盆友可不可以成功 
                    return true;
                visited[v]=0;//没有成功,那么就不加入第i组
            }
        }
    }
    return false;
} 
int main()
{
    while(~scanf("%d %d",&n,&m))
    {
        memset(map,false,sizeof(map));//false表示假设他们直接不喜欢一起玩
        memset(visited,0,sizeof(visited));
        int k,like;
        for(int i=0;i<n;i++)
        {
            scanf("%d",&k);
            for(int j=0;j<k;j++)
            {
                scanf("%d",&like);
                map[i][like]=true;
                map[like][i]=true;
            }
        }
        if(m>=n)//球的数量大于等于小孩的数量,肯定可以玩 
            printf("YES\n");
        else
        {
            if(dfs(0))
                printf("YES\n");
            else printf("NO\n");
        }
}
}

总结:

后面的3道有点思维含量和推算能力,在你们现阶段水平是本场防AK的题目。没做出来也不用灰心。有问题可在下面评论。下周再接再厉,看好你们噢。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值