2023寒假训练week1

Day1

蓝桥杯模拟赛

A [蓝桥杯 2020 省 AB1] 解码

连个限制条件:
1.将连续的几个相同字母写成字母 + 出现次数的形式
2.为了方便表达,小明不会将连续的超过9个相同的字符写成简写的形式。

#include <bits/stdc++.h>
using namespace std; 
string s;
int main(){
	cin>>s;
	for(int i=0; i<s.size(); i++){
		if((s[i]>='a'&& s[i]<='z') || (s[i]>='A' && s[i]<='Z'))
			cout << s[i];
		if(s[i]>='0' && s[i]<='9'){  //注意条件2,小于9
			int k = s[i]-'1';  //将字符转换成数字
			while(k--){
				cout << s[i-1];//s[i]是字符数字,s[i-1]是字母
			}
		}
	}
	return 0;
}

B [蓝桥杯 2020 省 AB2] 成绩分析

计算最高分、最低分和平均分。

#include<bits/stdc++.h>
using namespace std;
int main()
{
	int n;
	float sum=0;
	scanf("%d",&n);
	int maxx=-1;
	int minn=101;
	int num=n;
	while(n--){
		int s;
		scanf("%d",&s);
		sum+=s;  //求和
		maxx=max(s,maxx);  //最大值函数
		minn=min(s,minn);  //最小值函数
	}
	printf("%d\n",maxx);
	printf("%d\n",minn);
	printf("%.2f\n",sum/num);  //平均数
}

C [蓝桥杯 2020 省 B1] 整除序列

有一个序列,序列的第一个数是 n,后面的每个数是前一个数整除 2,请输出这个序列中值为正数的项。

#include<bits/stdc++.h>
using namespace std;
int main()
{
	long long n;
	scanf("%lld",&n);
	printf("%lld ",n);
	while(1){
		if(n/2){  //如果!0除以二并输出
			n/=2;
			printf("%lld ",n);
		}  //否则break
		else break;
	}
	return 0;
 } 

D [蓝桥杯 2020 省 AB3] 日期识别

#include <iostream>
using namespace std;
string s;

int main()
{
    string mons[13]= {"","Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"};
    cin >> s;
    string mon,day;
    mon=s.substr(0,3);  //月份的子串对应下标输出
    day=s.substr(3);  //日期的子串将字符数组转换成数字
    for(int i = 1;i<13;i ++)
        if(mon== mons[i]) cout << i << ' ';
    int d = (day[0] - '0') * 10 + (day[1] - '0');  //最多两位数
    cout <<d;
    return 0;
}

E [蓝桥杯 2020 省 AB2] 回文日期

就是输出最近的回文日期
注意:
1.输出最近的一个回文日期
2.输出最近的一个ABABABAB型回文日期
3.啊啊啊啊啊啊,不知道为什么,不能用to_string()函数将数字转换成字符串
4.于是版本一因为用了to_string没过,只好自己写一个转换函数,见版本二,还是tmd不过,洛谷卡bug了?
5.acwing两个版本都AC了,难道真的是洛谷的问题?
版本一:

#include<bits/stdc++.h> 

using namespace std;
int months[13] = {0,31,28,31,30,31,30,31,31,30,31,30,31};
bool check(int date) //判断日期是否合法
{
    int year = date / 10000;
    int month = date % 10000 / 100;
    int day = date % 100;
    if(!day || month < 0 || month > 12 ) return false;
    if(month != 2 && day >months[month]) return false;
    if(month == 2)
    {
        if((year%4==0&&year%100!=0)||(year%400==0)) //闰年特判
        {
            if(day > 29) return false;	//闰年2月29天 
        }
        else 
        {
            if(day > 28) return false;	//平年2月28天 
        }
    }
    return true;
}
bool check1(string s)  //判断是否是回文日期
{
    int len = s.size();
    for(int i = 0, j = len - 1; i < j ; i++,j--)  //双指针
    {
        if(s[i] != s[j]) return false;
    }
    return true;
}
bool check2(string s)  //判断是否是ABABBABA 型的回文日期
{
    if(check1(s))  //首先该日期要满足回文格式
    {
       if(s[0]!=s[2] || s[1]!= s[3] || s[0] == s[1]) return false;
       return true;
    }
}
int main()
{
    int date,flag=0;
    cin>>date;
    for(int i = date + 1; ;i++)
    {
        if(check(i))
        {
            string s = to_string(i);
            if(check1(s)&&!flag)   //输出回文日期
            {
                cout<<i<<endl;
                flag = 1;  //标记一下,避免多次输出
            }
            if(check2(s))  //输出ABABBABA 型的回文日期
            {
                cout<<i<<endl;
                return 0;
            }
        }
    }
    return 0;
}

版本二:

#include<bits/stdc++.h> 

using namespace std;
int months[13] = {0,31,28,31,30,31,30,31,31,30,31,30,31};
bool check(int date) //判断日期是否合法
{
    int year = date / 10000;
    int month = date % 10000 / 100;
    int day = date % 100;
    if(!day || month < 0 || month > 12 ) return false;
    if(month != 2 && day >months[month]) return false;
    if(month == 2)
    {
        if((year%4==0&&year%100!=0)||(year%400==0)) //闰年特判
        {
            if(day > 29) return false;
        }
        else 
        {
            if(day > 28) return false;
        }
    }
    return true;
}
bool check1(string s)  //判断是否是回文日期
{
    int len = s.size();
    for(int i = 0, j = len - 1; i < j ; i++,j--)  //双指针
    {
        if(s[i] != s[j]) return false;
    }
    return true;
}
bool check2(string s)  //判断是否是ABABBABA 型的回文日期
{
    if(check1(s))  //首先该日期要满足回文格式
    {
       if(s[0]!=s[2] || s[1]!= s[3] || s[0] == s[1]) return false;
       return true;
    }
}
int main()
{
    int date,flag=0;
    cin>>date;
    for(int i = date + 1; ;i++)
    {
        if(check(i))
        {
        	string s;
        	int in=i;
            for(int k=0;k<8;k++){//数字转换成字符串
            	s+=in%10+'0';
            	in/=10; 
            }
            reverse(s.begin(),s.end());
            if(check1(s)&&!flag)   //输出回文日期
            {
                cout<<i<<endl;
                flag = 1;  //标记一下,避免多次输出
            }
            if(check2(s))  //输出ABABBABA 型的回文日期
            {
                cout<<i<<endl;
                return 0;
            }
        }
    }
    return 0;
}

F[蓝桥杯 2020 省 B2] 平面切分

数学+去重

#include<bits/stdc++.h>
using namespace std;
const int N = 1010;
long double L[N][2];//存储A,B 
long long ans = 1; //初始一个平面 
int main(){
	int N;
	cin >> N;
	for(int i = 0;i < N;i++){
		cin >> L[i][0] >> L[i][1];
		bool flag = false; 
		for(int j = 0;j < i;j++){//判断是否重边
			if((L[j][0] == L[i][0]) && (L[j][1] == L[i][1])){
				flag = true;
				break;
			}
		}
		if(!flag){//若不重边,再判断交点数
			set<pair<long double,long double> > points;//记录每一条边加进来后与已有直线相交的不同位置的点 
			for(int k = 0;k < i;k++){
				if(L[k][0] == L[i][0]) continue;//斜率相同永远没有交点 
				//求交点 
				long double x = (L[i][1]-L[k][1])/(L[k][0]-L[i][0]);
				long double y = L[i][0]*x+L[i][1];
				points.insert(make_pair(x,y));//将x,y放进set中排序,自动去重 
			}
			ans += points.size()+1;
		}
	} 
	cout << ans;
	return 0;
}

G [蓝桥杯 2020 省 AB1] 走方格

比普通的dp多了一个限制条件,i和j均为偶数的时候,dp[i][j]=0//也就是不变

#include<bits/stdc++.h> 
using namespace std;
long long dp[1000][1000];	//走到n,m的方法数
int main() {
	int n,m;
	cin>>n>>m;

	for(int i=1;i<=n;i++)
		dp[i][1]=1;
	for(int i=1;i<=m;i++)
		dp[1][i]=1;
	
	for(int i=2;i<=n;i++){
		for(int j=2;j<=m;j++){
			if(i%2==0&&j%2==0)  //i和j均为偶数的时候,dp[i][j]=0也就是不变
				continue;
			dp[i][j]=dp[i][j-1]+dp[i-1][j];	
		}
	}
	cout<<dp[n][m]<<endl; 
	return 0;
}

H [蓝桥杯 2020 省 AB3] 乘法表

1.输出整齐的表格

2.进制转换(这是重点)——十分不幸的是,C++的进制转换库函数不能用,不过,自己动手丰衣足食嘛!

3.P 进制中大于等于 10 的数字用大写字母 A、B、C、··· 表示。这点万分重要因为我在比赛的时候没有看见这句换,只用了1,2条件,于是只得了30分emmm

4.等号左边大于等于10的数要用A,B,C...来替代,等号右边P进制数中大于等于10的数也要用A,B,C...来替代。


Day2

Dfs

1.回溯->出栈

2.递归->入栈
递归过程使用系统自带栈,因此我们不需要自己手写栈,只需要写递归程序即可

迷宫问题

找有多少条线路

#include<bits/stdc++.h>
using namespace std;
/*
2 2 1
1 1 2 2
1 2
*/ 
const int N=100;
int sx,sy,fx,fy;
bool g[N][N];
bool mapp[N][N];
int d[]={-1,0,1,0,-1};
int ans=0;
int n,m,t;

void dfs(int x,int y){
	if(x==fx&&y==fy){ 
		ans++;
		return;
	}
	for(int k=0;k<4;k++){
		int l,r;
		l=x+d[k],r=y+d[k+1];
		//注意:这不能用x+=因为x是局部变量。值的改变导致if判断出错
		if(l>=1&&r>=1&&l<=n&&r<=m&&!g[l][r]&&!mapp [l][r])//防止数组越界,且不能走到障碍 
		{
			mapp[l][r]=true;
			dfs(l,r);
			mapp[l][r]=false;
		}
	}
	return ;
}
int main()
{
	cin>>n>>m>>t;
	cin>>sx>>sy>>fx>>fy;
	while(t--){
		int gx,gy;
		cin>>gx>>gy;
		g[gx][gy]=true;//有障碍 
	}
/*
	for(int i=1;i<=n;i++){
		for(int j=1;j<=m;j++){
			cout<<g[i][j];		
		} 
		cout<<endl;	
	}
*/
	mapp[sx][sy]=true;//标记为已走过 
	dfs(sx,sy);
	cout<<ans<<endl;
	return 0;
}

n皇后问题

1.一行一行的递归
2.主对角线不行(x-y+n),副对角线不行(x+y),竖线不行(x),横线不行(y)

#include<bits/stdc++.h>
using namespace std;
const int N=100;
int pos[N];
int tot=0;
int n;	//棋盘大小 
bool vis[3][N]; 
void dfs(int u){ 
	if(u==n)//到第n行的时候
	{
		for(int i=0;i<n;i++)//输出 
			for(int j=0;j<n;j++){
				if(pos[i]==j) cout<<'Q';//pos记录每一行皇后放在哪个位子 
				else cout<<'*';
				if(j==n-1) cout<<endl;
			}
		cout<<endl;
		tot++;//记结果有几个 
	}
	else
	{
		for(int i=0;i<n;i++){
			if(!vis[0][i]&&!vis[1][u+i]&&!vis[2][u-i+n])
		//vis的第一个维度取0表示当前位 取1表示主对角线 取2表示副对角线
			{
				pos[u]=i;//第u行第i列放不放皇后 
				vis[0][i]=vis[1][u+i]=vis[2][u-i+n]=true;
				dfs(u+1);
				vis[0][i]=vis[1][u+i]=vis[2][u-i+n]=false;
			}
		}
	}
} 

 
int main()
{
	cin>>n;
	dfs(0);//第一行开始
	return 0; 
 } 

求细胞数量

  1. 细胞的定义为沿细胞数字上下左右若还是细胞数字则为同一细胞

  2. 0~9表示细胞

  3. 求给定矩形阵列的细胞个数。

#include<bits/stdc++.h>
using namespace std;
const int N=105;
int n,m;
char g[N][N];
int dx[]={-1,0,1,0};
int dy[]={0,1,0,-1};
bool st[N][N];//false没走过 

/*
4 10
0234500067
1034560500
2045600671
0000000089
*/

void dfs(int x,int y){ 
	st[x][y]=true;//标记走过
	
	for(int k=0;k<4;k++){
		int l,r;
		l=x+dx[k],r=y+dy[k];
		if(l>=0&&r>=0&&l<n&&r<m&&g[l][r]!='0'&&st[l][r]!=true){
			dfs(l,r);
		} 
	}
	return;
}

int main()
{
	cin>>n>>m;
	for(int i=0;i<n;i++){
		scanf("%s",g[i]);		
	}
/*
	for(int i=0;i<n;i++){
		for(int j=0;j<m;j++){
			cout<<g[i][j];		
		}
		cout<<endl;
	}
*/	int ans=0;
	for(int i=0;i<n;i++)
		for(int j=0;j<m;j++){
			if(g[i][j]!='0'&&st[i][j]!=true){
				dfs(i,j);
				ans++;
			}
		}
/*	cout<<"--------------"<<endl; 
	for(int i=0;i<n;i++){
		for(int j=0;j<m;j++){
			cout<<st[i][j];		
		}
		cout<<endl;
	}
*/
	cout<<ans<<endl;
	return 0;
}

Day3

SMU Winter 2023 Round #3 (Div.2)

A [eJOI2019] 异或橙子

B [传智杯 #4 决赛] 三元组

找出n之前的:i+j=k

#include <iostream>
using namespace std;
//有序好耶 
int main(){
    int t,n,s[105],ans=0;
    scanf("%d",&t);
    while(t--){
        scanf("%d",&n);
        for(int i=1;i<=n;i++){
            scanf("%d",&s[i]);
        }
        for(int i=1;i<=n;i++){	//依次遍历1~n 
            for(int j=i;j<=n;j++){	//依次遍历i~n 
                for(int k=j;k<=n;k++){	//依次遍历j~n 
                    if(s[k]==s[i]+s[j]){
                        ans++;
                    }
                }
            }
        }
    printf("%d\n",ans);
        ans=0;
    }
}

C [传智杯 #3 练习赛] 单位转换

1.全都转换成B
2.再将B转化成对应的进制

#include<bits/stdc++.h>
using namespace std;
//先将其转化为B,再转化为相应的第二个单位
string s;
double sum=0;
int main()
{
	int i; 
	cin>>s;
	while(s[i] >= '0' && s[i] <= '9') {
        sum = sum * 10 + s[i] - '0';
        i++;
    }
	if(s[i] == 'M')
        sum *= pow(2, 20);	//1MB=2^20B 
    else if(s[i] == 'G')	
        sum *= pow(2, 30);	//1GB=2^10B
    else if(s[i] == 'K')
        sum *= pow(2, 10);	//KB=2^10B
    
    if(s[s.size() - 2] == 'G')	//1B=2^(-30)GB 
        sum *= pow(2, -30);
    else if(s[s.size() - 2] == 'M')	//1B=2^(-20)MB
        sum *= pow(2, -20);
    else if(s[s.size() - 2] == 'K')	//1B=2^(-10)KB
        sum *= pow(2, -10);
    printf("%.6lf",sum);
 } 

D [CSP-J 2022] 乘方

用pow函数即可

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
int main()
{
	ll a,b;
	cin>>a>>b; 
	ll c=pow(a,b);
	if(c>1e9||c<0) cout<<-1<<endl;
	else cout<<c<<endl;
	return 0;
}

E [CSP-J2020] 直播获奖

#include<bits/stdc++.h>
using namespace std;
 
int arr[605] = {0};//数组这样开已经默认帮我们从大到小排序
int main(){
	int n, w;
	cin >> n >> w;
	for(int i = 1; i <= n; i++){
		int a;
		cin >> a;
		arr[a]++;//这个分数有几人
		//printf("a[%d]=%d ",a,arr[a]);
		int num=max(1,i*w/100);
		//cout<<"num:"<<num<<endl;
		int cnt=0;
		for(int j=600;j>=0;j--){
			cnt+=arr[j];//目前有几人
			if(cnt>=num){
				cout<<j<<" ";//每加入一个人就去判断分数线
				break;
			}
		}
	}
	cout << endl;
	return 0;
}

F [NWRRC2014]Grave

判断能否塞进这个长方形
只要这个正方形环能装下就行

#include<bits/stdc++.h>
using namespace std;
int a,b,c,d,e,f,g,h,x,y;
int main(){
	scanf("%d%d%d%d%d%d%d%d%d%d",&a,&b,&c,&d,&e,&f,&g,&h,&x,&y);
	if(c-g>=x&&d-b>=y){
		printf("Yes\n");
		return 0;
	}
	else if(e-a>=x&&d-b>=y){
		printf("Yes\n");
		return 0;
	}
	else if(c-a>=x&&f-b>=y){
		printf("Yes\n");
		return 0;
	}
	else if(c-a>=x&&d-h>=y){
		printf("Yes\n");
		return 0;
	}
	printf("No\n");
	return 0;
} 

G [CERC2013] Bus

1.递归
2.递推
递归:

#include<bits/stdc++.h>
using namespace std;
//递推公式:f(k-1)=f(k)*2+1;
int n;
int f(int x){
	if(x==n) return 0;
	else return f(x+1)*2+1;
} 
int main()
{
	int k;
	cin>>k;
	while(k--){
		cin>>n;
		cout<<f(0)<<endl;
	}
	return 0; 
 } 

递推:

#include<bits/stdc++.h>
using namespace std;
int t;
int k;
int n;

int main()
{
    cin>>t;
    while(t--)
    {
        n=0;//将n清0
        cin>>k;
        for(int i=1;i<=k;i++) 
        {
			n*=2;//将下车后剩下的人数乘2
			n++;//再将n+1
    	}
        cout<<n<<endl;//输出n
    }
    return 0;
}

H [NWRRC2014]Alarm Clock

1.将“:”前的数记为i,后的数记为j
2.注意前导零,输出的时候需要进行判断

#include<bits/stdc++.h>
using namespace std;
int n;
int num[]={6, 2, 5, 5, 4, 5, 6, 3, 7, 6};//下标的火柴数目 
int main(){
    cin>>n;
    for(int i=0;i<24;i++){
        for(int j=0;j<60;j++){
            int a=i/10,b=i%10,c=j/10,d=j%10;//个十百千位
            if((num[a]+num[b]+num[c]+num[d])==n){//相加是否等于n
            	if(i<10) printf("0%d",i);//前导零的输出
                else printf("%d",i);
                cout<<":";
                if(j<10) printf("0%d",j);
                else printf("%d",j);
                return 0;
            }
        }
    }
    cout<<"Impossible";
    return 0;
}

I [NOIP2005 普及组] 采药

01背包

#include<bits/stdc++.h>
using namespace std;
const int N=1e5;
int main()
{
	int t,m;
	cin>>t>>m;
	int ti[N],va[N];
	for(int i=0;i<m;i++){
		cin>>ti[i];
		cin>>va[i];
	}
	int dp[N];
	dp[0]=0;	//时间为0,价值为0	 
	for(int i=0;i<m;i++)//草药
		for(int j=t;j>=ti[i];j--){//时间 
			dp[j]=max(dp[j],dp[j-ti[i]]+va[i]);
		}
	cout<<dp[t]<<endl;
}

J 区间内的真素数

1.求素数——筛法
2.真素数——将数字反转,判断是否素数
3.数据范围1e5,直接先求出这个范围的所有素数

#include<bits/stdc++.h>
using namespace std;
//区间之间 
const int N=1e5+5;
bool a[N];
int ch(int n){//倒序 
	int sum=0;
	while(n){
		sum=sum*10+n%10;
		n/=10;
	}
	return sum;
}
int main()
{
	int n,m;
	cin>>n>>m;//先将所有的1~1e5素数标记 
	for(int i=0;i<=N;i++) a[i]=true;//筛法求素数 
	for(int i=2;i<=sqrt(N);i++){
		if(a[i]){
			for(int j=i*i;j<=N;j+=i){
				a[j]=false;
			}	
		}
	}
/*	for(int i=n;i<=m;i++){
		if(a[i]==true) 
			cout<<i<<" ";
	}
*/
	int cnt=0;
	for(int i=n;i<=m;i++){
		if(a[i]&&a[ch(i)]){
			if(cnt==0) printf("%d",i);
			if(cnt){
				printf(",%d",i);	
			}
			cnt++;
		}
	}
	if(cnt==0) cout<<"No"<<endl;
	return 0;
}

K 素数回文数的个数

1.跟上一题思路一样,直接求出范围内的所有素数
2.判断是否回文数

#include<bits/stdc++.h>
using namespace std;
const int N=1e4+10;
bool a[N];
//左右对称的素数 
bool check(int n){
	string s;
	while(n)	//数字转换成字符串 
	{
		s+=n%10+'0';
		n/=10;
	}
	//cout<<s<<" ";
	reverse(s.begin(),s.end());//翻转
	//cout<<s<<" ";
	//cout<<s.size()<<endl;
	for(int i=0,j=s.size()-1;i<j;i++,j--){//双指针判断是否回文
		//cout<<s[i]<<" "<<s[j]<<endl;
		if(s[i]!=s[j]) return false;
	}
	return true;
}
int main()
{
	int n;
	cin>>n;
	for(int i=0;i<=N;i++) a[i]=true;//筛法求素数 
	for(int i=2;i<=sqrt(N);i++){
		if(a[i]){
			for(int j=i*i;j<=N;j+=i){
				a[j]=false;
			}	
		}
	}
	/*
	for(int i=11;i<=n;i++)
		if(a[i]) cout<<i<<endl;
	*/
	int cnt=0;
	for(int i=11;i<=n;i++){
		if(check(i)&&a[i]){
			cnt++;
		}
	}
	cout<<cnt<<endl;
 } 

Day5

SMU Winter 2023 Round #4 (Div.2)

A.Chuanpai

数据范围x和y的范围是1~6
因此最大的牌面只能是12
直接枚举1~12就OK

#include<bits/stdc++.h>
using namespace std;
//x<=6,y<=6
int main()
{
	int t;
	cin>>t;
	while(t--){
		int x;
		cin>>x;
		if(x>12){//大于12
			cout<<0<<endl;
		}
		else {//1~12
			if(x==12||x==11){
			cout<<'1'<<endl;
			}
			if(x==10||x==9)
			cout<<'2'<<endl;
			if(x==8) {
			cout<<'3'<<endl;
			}
			if(x<=7){
			cout<<x/2<<endl;
			}	
		}	
	}
	return 0;
}

B.Hotpot

m次操作两个人轮流,第二个喜欢吃同样食物的人加m/2次幸福值,第一个人永远是0
那么我们就可以将两轮看做一个循环

#include<iostream>
#include<cstring>
using namespace std;
const int N=1e5+10;
struct f{
    int x;//每个人喜欢的食物
    int happy;//每个人的快乐值
}a[N];
int v[N];//用来记录锅子里有没有这个食材
long long n,k,m;
int main()
{
    int t;
    cin>>t;
    while(t--)
    {
        memset(v,0,sizeof(v));
        cin>>n>>k>>m;
        for(int i=0;i<n;i++){
        	cin>>a[i].x;
        	a[i].happy=0;
		}
        if(m>=2*n)
		{
	        for(int i=0;i<2*n;i++)
	        {
	            int j=i%n;
	            if(v[a[j].x]==0){//锅子里没有喜欢的食材
	            	v[a[j].x]++;//放进食材
				}else{//锅子里有喜欢的食材
	                v[a[j].x]--;//吃掉
	                a[j].happy++;//他快乐了
	            }
	        }
	        for(int i=0;i<n;i++)
	        	a[i].happy*=(m/(2*n));//以2*n为一次循环,有几次循环就让快乐值乘几
        }
        for(int i=0;i<m%(2*n);i++)//剩下的操作次数
        {
            int j=i%n;
            if(v[a[j].x]==0)v[a[j].x]++;
            else
            {
                v[a[j].x]--;
                a[j].happy++;
            }
        }
        for(int i=0;i<n;i++)
        {
            if(i)cout<<" ";
            cout<<a[i].happy;
        }
        cout<<endl;
    }
    return 0;
}

C.Triangle Pendant

D. Rock Paper Scissors

石头剪刀布游戏,让后出的那个人分数最大

#include <bits/stdc++.h>
using namespace std;
long long b1, b2, b3, d1, d2, d3, t;
int main()
{
	ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
	cin >> t;
	while(t -- )
	{
		cin >> b1 >> b2 >> b3 >> d1 >> d2 >> d3;
		long long ans = 0;
		if(b1 <= d2)
		{
			ans += b1;
			d2 -= b1;
			b1 = 0;
			if(b2 <= d3)
			{
				ans += b2;
				d3 -= b2;
				b2 = 0;
				if(b3 <= d1)
				{
					ans += b3;
					d1 -= b3;
					b3 = 0;
				}
				else if(b3 > d1)
				{
					ans += d1;
					b3 -= d1;
					d1 = 0;
				}
			}
			else if(b2 > d3)
			{
				ans += d3;
				b2 -= d3;
				d3 = 0;
				if(b3 <= d1)
				{
					ans += b3;
					d1 -= b3;
					b3 = 0;
				}
				if(b3 > d1)
				{
					ans += d1;
					b3 -= d1;
					d1 = 0;
				}				
			}
			
		}
		else if(b1 > d2)
		{
			ans += d2;
			b1 -= d2;
			d2 = 0;
			if(b2 <= d3)
			{
				ans += b2;
				d3 -= b2;
				b2 = 0;
				if(b3 <= d1)
				{
					ans += b3;
					d1 -= b3;
					b3 = 0;
				}
				else if(b3 > d1)
				{
					ans += d1;
					b3 -= d1;
					d1 = 0;
				}
			}
			else if(b2 > d3)
			{
				ans += d3;
				b2 -= d3;
				d3 = 0;
				if(b3 <= d1)
				{
					ans += b3;
					d1 -= b3;
					b3 = 0;
				}
				else if(b3 > d1)
				{
					ans += d1;
					b3 -= d1;
					d1 = 0;
				}				
			}			
		}
		long long aa = d1, bb = d2, cc = d3;
		d1 = d1 - min(d1,b1);
		d2 = d2 - min(d2,b2);
		d3 = d3 - min(d3,b3);
		b1 = b1 - min(aa,b1);
		b2 = b2 - min(bb,b2);
		b3 = b3 - min(cc,b3);
		long long  sum = d1 + d2 + d3 + b1 + b2 + b3;
		sum /= 2;
		ans -= sum;
		cout << ans << endl;
	}
}

E.Don’t Really Like How The Story Ends

F.Direction Setting

G. Hourly Coding Problem

H.Nihongo wa Muzukashii Desuz

字符串匹配和转换

#include<bits/stdc++.h>
using namespace std;
/*
10
machimasu
kaerimasu
nomimasu
yobimasu
shinimasu
kakimasu
ikimasu
kikimasu
isogimasu
kashimasu
*/
int main()
{
	int t;
	cin >> t;
	while(t -- )
	{
		string s;
		cin >> s;
		int len = s.length();
		// cout << "!!!!!!!!";
		if(len <=5) cout << s << endl;
		
		else if(s == "ikimasu" ) cout << "itte\n";
		
		else if(len == 6)
		{
			if(s == "gimasu")	cout << "ide" << endl;
			else if(s == "kimasu")	cout << "ite" << endl;
			else if(s == "mimasu" || s == "bimasu" || s == "nimasu")	cout << "nde" << endl;
			else if(s == "rimasu") cout << "tte" << endl;
		}
		else if(len >= 7)
		{
			string s1 = s.substr(len - 7, 7);
			string s2 = s.substr(len - 6, 6);
			if(s1 == "shimasu") cout << s.substr(0,len - 7) << "shite\n";
			else if(s1 == "chimasu") cout << s.substr(0,len - 7) << "tte\n";
			else if(s2 == "gimasu") cout << s.substr(0,len - 6) << "ide\n";
			else if(s2 == "kimasu") cout << s.substr(0,len - 6) << "ite\n";
			else if(s2 == "mimasu" || s2 == "bimasu" || s2 == "nimasu") cout << s.substr(0,len - 6) << "nde\n";
			else if(s2 == "rimasu") cout << s.substr(0,len - 6) << "tte\n";

		}
	}
	return 0;
}

I.Monster Hunter

J. Ants

K. K-skip Permutation

L. Spicy Restaurant

M.True Story

这题主要注意到从hour0开始,然后初始的时候飞机有一个始发时间
如果在最大的时间长度内跑,能到的人数就是最后能到机场不迟到的人数

#include<bits/stdc++.h>
/*
case1:
4 3 10 4
1 5 2 1
3 4 5
7 9 10
*/
using namespace std;
const long long N=2e5;
long long s[N];
long long t[N]; 
long long p[N];
//推迟时间-通知时间=能冲时间
//按能冲时间排序,能冲时间依次减小,就让速度最大的来试试? 
//能冲时间*最大速度>=他们之间的距离 
int main()
{
	long long n,k,x,p0;
	cin>>n>>k>>x>>p0;
	for(long long i=1;i<=n;i++){
		cin>>s[i];
	}
	for(long long i=1;i<=k;i++){
		cin>>t[i];
	}
	for(int i=1;i<=k;++i){
		cin>>p[i];
		p[i]-=t[i];
		p0=max(p0,p[i]);//找最大时间间隔
	}
//	if(s[0]*p0>=x) ans++;//0开始跑 
	int ans=0;
	for(int i=1;i<=n;++i)
		if(s[i]*p0>=x)
			ans++;
	cout<<ans<<"\n"; 
	return 0;
}
posted @ 2023-01-15 16:46  Is_Qinna  阅读(64)  评论(0)    收藏  举报