9.13-9.19算法题总结

Sakurako's Exam

cf1000分

问题描述:

给出a个1和b个2,请判断可否通过给这些数加负号使之合为0

我的解决方案:
#include<stdio.h>
int main()
{
	int num;
	scanf("%d", &num);
	for (int num1 = 1; num1 <= num; num1++)
	{
		int a;
		int b;
		scanf("%d %d", &a, &b);
		int c = a + b * 2;
		if (a % 2 == 1) {
			printf("NO\n");
		}
		else if (b % 2 == 0) {
			printf("YES\n");
		}
		else if (a >= 2) {
			printf("YES\n");
		}
		else {
			printf("NO\n");
		}
		
	}
	return 0;
}

2需要1来消掉,1只能自己消掉,首先奇数个1就不行,其次偶数个2则必行,若奇数个则此时只需要偶数个1中的两个来消掉这个2即可

学习代码:
#include<iostream>
using namespace std;
int n,a,b;
int main()
{
	cin>>n;
	while(n--)
	{
		cin>>a>>b;
		if(a!=0&&a%2==0||a==0&&b%2==0)
		puts("YES");
		else puts("NO");
	}
	return 0;
}

判断1只要是偶数个就必定比2大,此时只需要讨论1是否是0个


The Legend of Freya the Frog

1200分

问题概述:

在一个网格中,青蛙从00出发,必须先沿x方向,后沿y方向走,要求刚好到达目标点。输入a,b,k。其中ab为目的坐标,k为一次性最多走的步数,求出最少需要跳几次

我的解决方案:
#include <stdio.h>   
int main()
{
	int a, b, n, k;
	scanf("%d", &n);
	while (n--) {
		scanf("%d %d %d", &a, &b, &k);
		int reA, reB;
		reA = (a + k - 1) / k * 2 - 1;
		reB = (b + k - 1) / k * 2 ;
		printf("%d/n", ((reA > reB) ? reA : reB));
	}
	return 0;
}

听群里佬讲的思路才懂,重新写的代码。因为ab都最少需要/k次,然后可能差点余数,所以每个方向上至少需要(a+k-1)/k个k的步数,向上取整。a先走b后走,所以a方向-1,b方向不变,最后取两者中较大数即可

学习代码:
#include<bits/stdc++.h>
using namespace std;

int main(){
int t;cin>>t;
while(t--){
	    int x,y,k; cin>>x>>y>>k;
	    x=(x/k+(x%k!=0));
	    y=y/k+(y%k!=0);
	 
	    cout<<max(2*x-1,2*y)<<endl;
 
}
}

组内大佬用c++写的,思路都相同,应该是本题最佳思路了


Game with Doors

cf1100

问题概述:

100以内任取两个范围,假设每个范围内有一个人,避免两人相见,应关闭多少道门(两个数字中间一道门)

我的解决方案:
#include <stdio.h>   
int main()
{
	int n;
	scanf("%d", &n);
	while (n--) {
		int a, b, c, d;
		scanf("%d %d\n%d %d", &a, &b, &c, &d);
		/*scanf("%d %d", &c, &d);*/
		if (c < a && d > b || c > a && d < b) {
			int re = (c > a) ? d - c + 2 : b - a + 2;
			printf("%d\n", re);
		}
		else if (a == c && b == d) {
			int re = b - a;
			printf("%d\n", re);
		}
		else if (c == a || b == d) {
			int re = (c == a) ? ((b > d) ? d - c + 1 : b - a + 1) : ((a > c) ? b - a + 1 : d - c + 1);
			printf("%d\n", re);
		}
		else if(c<d<a<b){
			printf("%d\n",(a-d>1)?2:1);
		}
		else if(a<b<c<d){
			printf("%d\n",(c-b>1)?2:1);
		}
	}
	return 0;
}

分成几种情况讨论,即1:某个范围包含在某个之中,此时卡住小范围内的全部和两边即可

2:两个范围相同,此时卡住中间的即可    3:两个范围中某一个数相同,此时判断另一个哪个大,卡住小范围加1即可

4:两个范围没有交集,判断如果相距1,即1,否则关闭两边即2

学习代码:
#include <bits/stdc++.h>
 
using namespace std;
 
int main() {
 
	int t; cin>>t;
	while(t--) {
		int l,r,a,b; cin>>l>>r>>a>>b;
        int v=min(r,b)-max(l,a),ans=2;
        if (l==a) ans--;
        if (b==r) ans--;
        if (v<0) ans=0;
        cout<<max(1,ans+max(0,v))<<endl;
	}
}

思路应该是的一样的,四张情况,这个c++代码更简洁。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值