调式小记 第2次测训赛 20模2-Cc3-最大公约数20省1-3- 合并检测20省1-5- 矩阵17省7-日期问题 17省8-包子凑数

**1、20模2-Cc3-最大公约数
https://vijos.org/d/gadflycq/p/1035

考试时,做错了,错误原因:①70044写成7044,②找的是最大公约数,要找的是最大那个;
提交时错误的代码:

#include <iostream>

using namespace std;

int main()
{
    int a=7044,b=113148;
    for(int i=b;i>=2;i--){
        if(b%i==0&&a%i==0){
            cout<<i;
            break;
        }
    }
    return 0;
}

修改后正确的代码一:

#include <iostream>

using namespace std;

int main()
{
    int a=70044,b=113148;
    for(int i=a;i>=2;i--){
        if(b%i==0&&a%i==0){
            cout<<i;
            break;
        }
    }
    return 0;
}

修改后正确的代码二:

#include <bits/stdc++.h>

using namespace std;

int main() {
	int m=0;
	for(int i=1;i<=70044;i++){
		if(113148%i==0&&70044%i==0){
			m=i;
		}
	}
	cout<<m;
	
	
	return 0;
}

**2、20省1-3- 合并检测
https://vijos.org/d/gadflycq/p/1038
【问题描述】
新冠疫情由新冠病毒引起,最近在 A 国蔓延,为了尽快控制疫情, A 国准备给大量民众进病毒核酸检测。
然而,用于检测的试剂盒紧缺。
为了解决这一困难,科学家想了一个办法:合并检测。即将从多个人( k个)采集的标本放到同一个试剂盒中进行检测。如果结果为阴性,则说明这 k个人都是阴性,用一个试剂盒完成了 k 个人的检测。如果结果为阳性,则说明至少有一个人为阳性,需要将这 k 个人的样本全部重新独立检测(从理论上看,如果检测前 k − 1 个人都是阴性可以推断出第 k 个人是阳性,但是在实际操作中不会利用此推断,而是将 k 个人独立检测),加上最开始的合并检测,一共使用了 k + 1 个试剂盒完成了 k 个人的检测。
A 国估计被测的民众的感染率大概是 1%,呈均匀分布。请问 k 取多少能最节省试剂盒?

【输入】
没有输入。

【输出】
输出一个整数。
考试时错误,是因为复制代码时,多了个注释新号;
在这里插入图片描述
在这里插入图片描述
**3、20省1-5- 矩阵
https://vijos.org/d/gadflycq/p/1039
【问题描述】
把 1 ∼ 2020 放在 2 × 1010 的矩阵里。要求同一行中右边的比左边大,同一列中下边的比上边的大。一共有多少种方案?
答案很大,你只需要给出方案数除以 2020 的余数即可。

【输入】
没有输入。

【输出】
输出一个整数。

【提示】
把答案放在输出语句中输出,例如C/C++语言可以用printf或cout。
注意:需要输出的是一个整数,不要输出任何多余内容。

首先是对题目意思的理解,2*1010是2行1010列。我们从 2020 个数里选 1010 个放入第一行,那么为了满足同一行中右边的比左边大,只能升序排列。同理剩下的 1010 个放入第二行的也要升序排列,那么只要对于任意 i∈[1,1010] 都满足第二行第 i 个大于第一行第 i 个就是一种合法方案。从前往后枚举,用dp[i][j] 表示当前枚举了 i 个数,其中 j 个放入第一行的合法方案数。
我提交的错误的代码:
在这里插入图片描述
还有数组下标越界啦,开到dp[2020][2020]以上才得行,dp[2020][1010]不得行的哦。
修改后的代码一:

#include<bits/stdc++.h>
using namespace std;
long long dp[2050][2050];//dp[i][j]表示前i个数放前j到第一行的方案数;
int main()
{   long long int i,j;
    memset(dp,0,sizeof(dp));
    dp[1][1]=1;//dp[2][1]=1;
    for( i=2;i<=2020;i++){
        for(j=1;j<=i;j++){
                dp[i][j]=(dp[i][j]+dp[i-1][j-1])%2020;
                if(i-j<=j)//数 行数   行数
                {dp[i][j]=(dp[i][j]+dp[i-1][j])%2020;}

        }
    }
    printf("%lld\n",dp[2020][1010]);

return 0;
 }

参考别的代码:

#include<bits/stdc++.h>
using namespace std;
int N = 2020, mod = 2020;
long long dp[N][N];
int main() {
   long long cnt = 0;
    dp[1][1] = 1;// 1必然放在第一行
    for (int i = 1; i <= 2020; ++i) {
        for (int j = 1; j <= i; ++j) {
            dp[i][j] += dp[i - 1][j - 1];// 将第i个数放第一行
            if (i - j <= j)
                /*
                    因为是正向枚举,后面的数只会越来越大
                    要随时保持第一行的个数不能比第二行的少
                    否则必然出现这一列第二行比第一行小的情况
                */
                dp[i][j] += dp[i - 1][j];
            dp[i][j] %= mod;
        }
        
    }
    cout << dp[2020][1010];
}

**4、17省7-日期问题
https://vijos.org/d/gadflycq/p/5aaba0b8d3d8a13712240a9c
小明正在整理一批历史文献。这些历史文献中出现了很多日期。小明知道这些日期都在1960年1月1日至2059年12月31日。令小明头疼的是,这些日期采用的格式非常不统一,有采用年/月/日的,有采用月/日/年的,还有采用日/月/年的。更加麻烦的是,年份也都省略了前两位,使得文献上的一个日期,存在很多可能的日期与其对应。

比如02/03/04,可能是2002年03月04日、2004年02月03日或2004年03月02日。

给出一个文献上的日期,你能帮助小明判断有哪些可能的日期对其对应吗?

输入
一个日期,格式是"AA/BB/CC"。 (0 <= A, B, C <= 9)

输出
输出若干个不相同的日期,每个日期一行,格式是"yyyy-MM-dd"。多个日期按从早到晚排列。

样例
输入
02/03/04

输出
2002-03-04
2004-02-03
2004-03-02

错误代码:

#include <bits/stdc++.h>

using namespace std;

typedef struct{
    int year, month, day;
}date;

bool isyn(int y){
    return (y % 4 == 0) || (y % 100 && y % 400 == 0);//ture false
}

void print(const date &d){
    printf("%02d-%02d-%02d\n", d.year, d.month, d.day);//
}

bool compare(const date &d1, const date &d2){
    if(d1.year != d2.year){
        return d1.year < d2.year;
    }
    if(d1.month != d2.month){
        return d1.month < d2.month;
    }
    return d1.day < d2.day;
}

bool check(const date &d){
    static int month_days[] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};//12月
    if(isyn(d.year)){//闰年
        month_days[2] = 29;
    }else{
        month_days[2] = 28;
    }

    if(d.year < 1960 || d.year > 2059){
        return false;
    }
    if(d.month < 1 || d.month > 12){
        return false;
    }
    if(d.day < 1 || d.day > month_days[d.month]){
        return false;
    }
}

int main()
{
    int a, b, c;
    scanf("%d/%d/%d", &a, &b, &c);
    date d[6] = {
        {2000 + a, b, c},
        {1900 + a, b, c},
        {2000 + c, a, b},
        {1900 + c, a, b},
        {2000 + c, b, a},
        {1900 + c, b, a}
    };
    sort(d, d + 6, compare);//自定义排序规则
    for(int i = 0; i < 6; ++ i){
        if(check(d[i])){
            print(d[i]);
        }
    }
    return 0;
}

错误情况
在这里插入图片描述
醒醒,改Bug啦!!

关键字:闰年判断,枚举,输入
#include<bits/stdc++.h>
using namespace std;
int check(int year,int mon,int day){
	
	if(year%400==0||(year%100!=0&&year%4==0))  {
		if(mon==2&&day>29) return 0;
		
	}
	else
        {if(mon==2&&day>28) return 0;
	
	
	    else return 1;
		}
	return 1;	
	
}
void shuchu(int fi,int se,int th){
	int year,mon,day;
	for(year=1960;year<=2059;year++)
		for(mon=1;mon<=12;mon++)
			for(day=1;day<=31;day++){//有采用年/月/日的,有采用月/日/年的,还有采用日/月/年的。
				//年月日 
				if(year%100==fi&&mon==se&&day==th){
					if(check(year,mon,day))
					printf("%d-%02d-%02d\n",year,mon,day);	
					
				}
				 
				if(mon==fi&&day==se&&year%100==th&&fi!=th)
				printf("%d-%02d-%02d\n",year,mon,day);	
				
				//ri  year mon
				if(day==fi&&mon==se&&year%100==th&&fi!=se)
				printf("%d-%02d-%02d\n",year,mon,day);	
				
			}
		
	
	
}
int main(){
	int fi,se,th;
    int xg1,xg2;
	//scanf("%d/%d/%d",&fi,&se,&th);
	scanf("%d%c%d%c%d",&fi,&xg1,&se,&xg2,&th);
	shuchu(fi,se,th);	
	return 0;
}

**5,17省8-包子凑数

https://vijos.org/d/gadflycq/contest/60135eeef413621b7335de73/5aabd01bd3d8a13712240ba7

小明几乎每天早晨都会在一家包子铺吃早餐。他发现这家包子铺有N种蒸笼,其中第i种蒸笼恰好能放Ai个包子。每种蒸笼都有非常多笼,可以认为是无限笼。

每当有顾客想买X个包子,卖包子的大叔就会迅速选出若干笼包子来,使得这若干笼中恰好一共有X个包子。比如一共有3种蒸笼,分别能放3、4和5个包子。当顾客想买11个包子时,大叔就会选2笼3个的再加1笼5个的(也可能选出1笼3个的再加2笼4个的)。

当然有时包子大叔无论如何也凑不出顾客想买的数量。比如一共有3种蒸笼,分别能放4、5和6个包子。而顾客想买7个包子时,大叔就凑不出来了。

小明想知道一共有多少种数目是包子大叔凑不出来的。

输入
第一行包含一个整数N。(1 <= N <= 100)
以下N行每行包含一个整数Ai。(1 <= Ai <= 100)

输出
一个整数代表答案。如果凑不出的数目有无限多个,输出INF。
输入:
2
4
5

程序应该输出:
6

再例如,
输入:
2
4
6

程序应该输出:
INF

考试时提交是runerro!!凸(艹皿艹 )我输入数组那里没&。。。。第一次犯这种低级错误,必须是最后一次!!

在这里插入图片描述

考试时候,没写&。。。的代码

#include <bits/stdc++.h>
using namespace std;
int n;
int a[102];
int f[10020];
int gcd(int x,int y)
{
    return x%y==0? y:gcd(y,x%y);
}
int main ()
{
    cin>>n;
    for(int i=1;i<=n;i++)
        scanf("%d",a[i]);
    memset(f,0,sizeof(f));
        f[0]=1;
    int num=a[1];
    for(int i=2;i<=n;i++)
        num=gcd(num,a[i]);
    if(num!=1)
        cout<<"INF";
    else{
        for(int i=1;i<=n;i++)
        for(int j=0;j+a[i]<=10000;j++)
        if(f[j])
        f[j+a[i]]=1;
        int ans=0;
        for(int i=1;i<=10000;i++)
        if(f[i]==0)
        ans++;
        cout<<ans;}
    return 0;
}
#include <bits/stdc++.h>
using namespace std;
int n;
int a[102];
int f[10020];
int gcd(int x,int y)
{
    return x%y==0? y:gcd(y,x%y);
}
int main ()
{
    cin>>n;
    for(int i=1;i<=n;i++)
        scanf("%d",&a[i]);
    memset(f,0,sizeof(f));
        f[0]=1;
    int num=a[1];
    for(int i=2;i<=n;i++)
        num=gcd(num,a[i]);
    if(num!=1)
        cout<<"INF";
    else{
        for(int i=1;i<=n;i++)
        for(int j=0;j+a[i]<=10000;j++)
        if(f[j])
        f[j+a[i]]=1;
        int ans=0;
        for(int i=1;i<=10000;i++)
        if(f[i]==0)
        ans++;
        cout<<ans;}
    return 0;
}

**6,基础训练—数的读法

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值