7.23考试总结

7.23考总

T3:

可将原式

aix+y=cia_i\cdot x+y=c_i

快速转化为:

(ciy)÷x=ai(c_i-y)\div x=a_i

可发现,这里的 yy 很像除法中的余数,那么只要判断数组cmodxc\mod x是否不变,如果有变则无解,然后找到最小值minimini,答案就是minixmini-x

Tip:这里还要特判mini<xmini< x是否为真,如果成立则无解

AC code:

#include<bits/stdc++.h>
#define int long long//祖宗的凝视
#define endl "\n"//个人习惯
using namespace std;
const int maxn=1e5+5;
int x,n;
int c[maxn],mini=1e18;
signed main(){
	cin>>n>>x;
	for(int i=1;i<=n;i++){//输入
		cin>>c[i];
	}
	int haha=c[1]%x;//求余
	for(int i=1;i<=n;i++){
		if(c[i]%x!=haha){//判断是否同余
			cout<<"-1"<<endl;//不同余,无解
			return 0;
		} 
	}
	for(int i=1;i<=n;i++){
		mini=min(mini,c[i]);//最小值mini
	}
	if(mini<x){//特判
		cout<<"-1"<<endl;
	}
	else{
		cout<<mini-x<<endl;//answer
	}
	return 0;
}

T4

不难发现,hih_i非常小,所以可以枚举两根柱子的高度,再枚举其中一根柱子的高度,另一根柱子的高度就出来了,然后ansans统计一下。

这里用一个桶来统计每个高度上有几根柱子,ansans只要加两根柱子的最小值即可,因为如果有一根柱子没有,那么就达不到,如果两根都有,则要选更小的。

统计完之后判断一下,如果ansans更大,则答案更新,答案的数量变为11,如果ansans等于现在的答案,则答案的数量+1+1。时复为

O((6×103)(3×103)O((6\times 10^3)*(3\times10^3)

AC code:

#include<bits/stdc++.h>
#define int long long
#define endl "\n"
using namespace std;
const int maxn=1e6+5;
int n,h[maxn];
int vis[maxn];
signed main(){
	cin>>n;
	for(int i=1;i<=n;i++){
		cin>>h[i];
		vis[h[i]]++;//桶标记
	}
	int sum=0,res=0;
	for(int i=1;i<=6000;i++){//枚举高度
		int ans=0;
		for(int j=1;j<=i/2;j++){//枚举石柱
			int x=i-j;//求另一根石柱的高度
			if(j==x) ans+=vis[x]/2;//特判
			else ans+=min(vis[x],vis[j]);//ans更新
		}
		if(ans>sum){//如果更大
			res=1;//数量变为1
			sum=ans;//更新
		}
		else if(ans==sum){//如果一样
			res++;//数量++
		}
	}
	cout<<sum<<' '<<res;//输出撒花✿✿ヽ(°▽°)ノ✿
	return 0;
}

T6

考虑贪心,将每一个块按右端点排序,优先选右边的点就没了。(其余看代码)

AC code:

#include<bits/stdc++.h>
#define int long long
#define endl "\n"
using namespace std;
const int maxn=1e5+5;
int n;
bool vis[maxn];
struct Node{
	int x,y,c;	
}a[maxn];
bool cmp(Node x,Node y){
	return x.y<=y.y;
}
signed main(){
	cin>>n;
	for(int i=1;i<=n;i++){
		cin>>a[i].x>>a[i].y>>a[i].c;//输入
	}
	sort(a+1,a+n+1,cmp);//按右端点排序
	int ans=0,cnt=0;
	for(int i=1;i<=n;i++){//枚举每个块
		cnt=0;
		for(int j=a[i].x;j<=a[i].y;j++){//枚举每个点
			if(vis[j]){//已经选过了
				cnt++;//统计
			}
		}
		if(cnt>=a[i].c){//已经达到了c
			continue; 
		}  
		for(int j=a[i].y;j>=a[i].x;j--){//从右端点开始枚举
			if(!vis[j]){//没选
				vis[j]=1;//选了
				cnt++;//统计
				ans++;//答案+1
				if(cnt==a[i].c){//已经选完了
					break;
				}
			} 
		}
	}
	cout<<ans<<endl;
	return 0;
}
posted @   KK_SpongeBob  阅读(5)  评论(0编辑  收藏  举报  
相关博文:
阅读排行:
· 百万级群聊的设计实践
· 永远不要相信用户的输入:从 SQL 注入攻防看输入验证的重要性
· 全网最简单!3分钟用满血DeepSeek R1开发一款AI智能客服,零代码轻松接入微信、公众号、小程
· .NET 10 首个预览版发布,跨平台开发与性能全面提升
· 《HelloGitHub》第 107 期
点击右上角即可分享
微信分享提示