【比赛】高一高考集训欢乐赛

IOI 赛制的超级码力赛,使我的大脑疯狂旋转。

T1 Efim与奇怪的成绩 100Pts

题面

小模拟。
显然,如果能四舍五入,那么一定会先四舍五入前面的。
大力模拟即可。注意特判一些细节。

点击查看代码
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
int n,t,len;
string s;
int main(){
	freopen("grade.in","r",stdin);
	freopen("grade.out","w",stdout);
	cin>>n>>t>>s;
	while(len<n&&s[len]!='.')len++;
	while(len<n&&s[len]<'5')len++;
	if(len==n)return cout<<s,0;
	while(t&&s[len]>='5'){
		n=len--;;
		if(s[len]=='.'){
			s[--len]++;
			while(len>0&&s[len]>'9'){
				s[len]='0';
				s[--len]++;
			}
			if(len==0&&s[len]>'9'){
				s="10"+s.substr(1,n);
			}
			break;
		}
		t--;
		s[len]++;
	}
	if(s[n-1]=='.')n--;
	for(int i=0;i<n;i++){
		cout<<s[i];
	}
	return 0;
}

T2 美丽的IP地址 100Pts

题面

搜索题,半个大模拟。
枚举半个回文串的长度,枚举每位的数字,检验是否可行,然后做完了。
细节极多。

点击查看代码
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
int n,ok[15],x;
ll ans;
ll f[15][15];
ll a[15],b[15],cnt;
bool check(int x,int y){
	if(a[x]==0&&y-x+1>1)return 0;
	int now=0;
	for(int i=x;i<=y;i++)now=(now<<3)+(now<<1)+a[i];
	return (now<=255);
}
int query(int x){
	for(int i=0;i<=9;i++)if(ok[i]&&(!b[i]))return 0;
	memset(f,0,sizeof(f));
	for(int i=1;i<=x;i++){
		if(i<4)f[i][1]=check(1,i)?1:0;
		for(int j=max(1,i-2);j<=i;j++){
			if(check(j,i)){
				for(int k=2;k<=4;k++)f[i][k]+=f[j-1][k-1];
			}
		}
	}
	return f[x][4];
}
void dfs(int x,int len){
	if(x<=len){
		for(int i=0;i<=9;i++){
			if(ok[i]){
				a[x]=a[2*len-x+1]=i;
				b[i]++;
				dfs(x+1,len);
				b[i]--;
			}
		}
	}
	else{
		ans+=query(len*2);
		for(int i=len*2+1;i>len+1;i--)a[i]=a[i-1];
		for(int i=0;i<=9;i++){
			if(ok[i]){
				a[len+1]=i;
				b[i]++;
				ans+=query(len*2+1);
				b[i]--;
			}
		}
		for(int i=len+1;i<=len*2+1;i++)a[i]=a[i+1];
	}
}
int main(){
	#ifdef ONLINE_JUDGE
		freopen("ipadd.in","r",stdin);
		freopen("ipadd.out","w",stdout);
	#endif
	cin>>n;
	if(n>6)return cout<<0,0;
	for(int i=1;i<=n;i++){
		cin>>x;
		ok[x]=1;
	}
	for(int k=2;k<=6;k++)dfs(1,k);
	cout<<ans;
	return 0;
}

T3 装饰 100Pts

题面

思维题,但思维含量不高。
有人开赛 5min 就切了的题能有啥难度

由于每张桌子要用三种颜色不完全相同的气球装饰,所以:

  • 当数量最多的气球远大于另两种气球数量之和的 2 倍时,答案就是另两种气球数量之和;
  • 否则,答案就是三种气球数量之和除以 3

由于只有这两种情况,所以直接取这两种情况的最小值即可。

点击查看代码
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
ll T,a[4];
bool check(int x){
	return (a[1]+a[2]>=x);
}
int main(){
	#ifdef ONLINE_JUDGE
		freopen("decorate.in","r",stdin);
		freopen("decorate.out","w",stdout);
	#endif
	cin>>T;
	while(T--){
		cin>>a[1]>>a[2]>>a[3];
		sort(a+1,a+1+3);
		ll maxn=(a[1]+a[2]+a[3])/3;
		cout<<min(a[1]+a[2],maxn)<<"\n";
	}
	return 0;
}

T4 最大子矩阵Largest Submatrix 20Pts

题面

单调队列优化 DP。

赛时打了个 O(n6) 暴力,然后没看见多测,5020

点击查看代码
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=1005;
ll w[N];
ll n,m,ans;
ll up[N][N];
char str[N][N];
bool a[N][N];
bool pro(char c,char t){
	if(c=='w')return t=='a'||t=='b';
	if(c=='x')return t=='c'||t=='b';
	if(c=='y')return t=='c'||t=='a';
	if(c=='z')return 1;
	return c==t;
}
void work(char c){
	for(int i=1;i<=n;i++){
		for(int j=1;j<=m;j++){
			a[i][j]=pro(str[i][j],c);
			up[i][j]=a[i][j]?up[i-1][j]+1:0;
		}
	}
	stack<ll> s;
	for(int i=1;i<=n;i++){
		for(int j=1;j<=m;j++){
			ll sum=0;
			while(!s.empty()&&s.top()>=up[i][j]){
				sum+=w[s.top()];
				ans=max(ans,s.top()*sum);
				s.pop();
			}
			sum++;
			s.push(up[i][j]);
			w[s.top()]=sum; 
		}
		ll sum=0;
		while(!s.empty()){
			sum+=w[s.top()];
			ans=max(ans,s.top()*sum);
			s.pop();
		}
	}
}
int main(){
	#ifdef ONLINE_JUDGE
		freopen("matrix.in","r",stdin);
		freopen("matrix.out","w",stdout);
	#endif
	while(~scanf("%lld%lld",&n,&m)){
		ans=0;
		for(int i=1;i<=n;i++)scanf("%s",str[i]+1);
		work('a');work('b');work('c');
		printf("%lld\n",ans);
	}
	return 0;
}

T5 中国象棋 0Pts

题面

DP,但不是状压。

fi,j,k 表示枚举到第 i 行,有 j 列有一个炮,k 列有两个炮的方案数。

大力转移即可。

赛时一直在想怎么打状压的 60 分,最后两分钟才狼狈地去打爆搜,然后没交上,300

点击查看代码
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=105;
const int mod=9999973;
ll n,m,ans;
ll f[N][N][N];
ll C(int n){
	return (n*(n-1)/2)%mod;
}
int main(){
	#ifdef ONLINE_JUDGE
		freopen("chess.in","r",stdin);
		freopen("chess.out","w",stdout);
	#endif
	cin>>n>>m;
	f[0][0][0]=1;
	for(int i=1;i<=n;i++){
		for(int j=0;j<=m;j++){
			for(int k=0;k<=m-j;k++){
				f[i][j][k]=f[i-1][j][k];
				if(k>=1)f[i][j][k]+=f[i-1][j+1][k-1]*(j+1);
				if(j>=1)f[i][j][k]+=f[i-1][j-1][k]*(m-j-k+1);
				if(k>=2)f[i][j][k]+=f[i-1][j+2][k-2]*(C(j+2));
				if(k>=1)f[i][j][k]+=f[i-1][j][k-1]*j*(m-j-k+1);
				if(j>=2)f[i][j][k]+=f[i-1][j-2][k]*C(m-j-k+2);
				f[i][j][k]%=mod;
			}
		}
	}
	for(int i=0;i<=m;i++){
		for(int j=0;j<=m;j++){
			ans=(ans+f[n][i][j])%mod;
		}
	}
	cout<<ans;
	return 0;
}

T6 奇妙的 Fibonacci 30Pts

题面

牛逼题,但过于牛逼了。

证明不会,看DZ博客吧。

点击查看代码
#include<bits/stdc++.h>
#define int ll
using namespace std;
typedef long long ll;
const int N=1e7+5;
const int mod=1e9+7;
int vis[N],p[N],minn[N];
int tot;
int sum[N],cnt[N],els[N];
int q,q1,a,b,c;
void init(){
	cnt[1]=sum[1]=1;
	for(int i=2;i<=N-5;i++){
		if(!vis[i]){
			p[++tot]=i;
			minn[i]=els[i]=1;
			cnt[i]=2;
			sum[i]=1ll*i*i%mod+1;
		}
		for(int j=1;j<=tot&&i*p[j]<=N-5;j++){
			int t=i*p[j];
			vis[t]=1;
			if(i%p[j]==0){
				minn[t]=minn[i]+1;
				els[t]=els[i];
				cnt[t]=(cnt[i]/(minn[i]+1))*(minn[t]+1);
				sum[t]=(sum[els[i]]+1ll*sum[i]*p[j]%mod*p[j]%mod)%mod;
				break;
			}
			cnt[t]=cnt[i]+1;
			minn[t]=1;
			els[t]=i;
			cnt[t]=cnt[i]*2;
			sum[t]=(sum[i]+1ll*sum[i]*p[j]%mod*p[j]%mod)%mod;
		}
	}
}
int ans1,ans2;
main(){
	freopen("fibo.in","r",stdin);
	freopen("fibo.out","w",stdout);
	init();
	cin>>q>>q1>>a>>b>>c;
	a%=c;b%=c;
	while(q--){
		ans1=(ans1+cnt[q1]+(q1&1))%mod;
		ans2=(ans2+sum[q1]+(q1&1)*4)%mod;
		q1=(1ll*q1*a+b)%c+1;
	}
	cout<<ans1<<"\n"<<ans2;
	return 0;
}
posted @   萝卜甜了  阅读(24)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· winform 绘制太阳,地球,月球 运作规律
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· AI 智能体引爆开源社区「GitHub 热点速览」
· 写一个简单的SQL生成工具
· Manus的开源复刻OpenManus初探
点击右上角即可分享
微信分享提示