其他分享
首页 > 其他分享> > 2022 Winter Individual Contest - A(补题+反思)

2022 Winter Individual Contest - A(补题+反思)

作者:互联网

https://vjudge.csgrandeur.cn/contest/475668#overview
H - Nine Packs
没想出来用01背包,脑子不太灵光。
看题解后第一个想法就是这也太神奇了吧,还能这样用。

整理完这道题后感觉01背包问题就是:
一组数据,存在某种约束条件的情况下,有目的性的取与不取的问题.

#include<bits/stdc++.h>
using namespace std;
const int N=1e5+10,INF=0x3f3f3f3f;
int n,suma,arr[N],dpa[N];
int m,sumb,brr[N],dpb[N];
//dpa[i]表示,i这个数最少能用几个arr[i]的和表示,apa[0]=0; 
int main(){
	ios::sync_with_stdio(false);
    cin.tie(0);  cout.tie(0);
    
    memset(dpa,0x3f,sizeof dpa);
    memset(dpb,0x3f,sizeof dpb);
    
	cin>>n;dpa[0]=0;
    for(int i=1;i<=n;i++) cin>>arr[i],suma+=arr[i];
	cin>>m;dpb[0]=0;
	for(int i=1;i<=m;i++) cin>>brr[i],sumb+=brr[i];
	
	for(int i=1;i<=n;i++){
		for(int j=suma;j>=arr[i];j--){
			if(dpa[j-arr[i]]!=INF){
				dpa[j]=min(dpa[j-arr[i]]+1,dpa[j]);
			}
		}
	}
	for(int i=1;i<=m;i++){
		for(int j=sumb;j>=brr[i];j--){
			if(dpb[j-brr[i]]!=INF){
				dpb[j]=min(dpb[j-brr[i]]+1,dpb[j]);
			}
		}
	}
	suma=min(suma,sumb);
	int minn=INF;
	for(int i=1;i<=suma;i++){
		if(dpa[i]==INF||dpb[i]==INF) continue;
		minn=min(dpa[i]+dpb[i],minn);
	}
	if(minn==INF) cout<<"impossible";
	else cout<<minn;
}

A - A New Alphabet
简单题更要小心陷阱啊

cout<<"\\ \\n \\t";//转义字符输出

C - Big Truck
比赛时直接改的模板,现在自己默写一遍

#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const int N=1e3+10;

int n,arr[N],gp[N][N],dis[N],vis[N],cnt[N]; 
int m;

void dijkstra(){
	memset(dis,0x3f,sizeof dis);
	
	dis[1]=0;cnt[1]=arr[1];
	for(int j=1;j<=n;j++){
		int k=0;
		for(int i=1;i<=n;i++){
			if(!vis[i]&&(k==0||dis[i]<dis[k])){
				k=i;
			}
		}
		vis[k]=1;
		for(int i=1;i<=n;i++){
			if(dis[i]>dis[k]+gp[k][i]){
				dis[i]=dis[k]+gp[k][i];
				cnt[i]=cnt[k]+arr[i];
			}
			else if(dis[i]==dis[k]+gp[k][i]){
				cnt[i]=max(cnt[i],cnt[k]+arr[i]);
			}
		}
	}
}

int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);  cout.tie(0);

    cin>>n;
    for(int i=1;i<=n;i++) cin>>arr[i];
    cin>>m;
    int a,b,c;
    memset(gp,0x3f,sizeof gp);
    for(int i=1;i<=m;i++){
    	cin>>a>>b>>c;
    	gp[a][b]=gp[b][a]=c;
	}
	

	dijkstra();
	if(dis[n]==0x3f3f3f3f) cout<<"impossible";
	else cout<<dis[n]<<" "<<cnt[n];
    return 0;
}

G - Inverse Factorial

不断取模相等就过了,可能数据太水了吧
赛后看题解正解应该就是通过两边取log10把左边的大数转化为它的位数,右边的乘转为加,极大的减小了数据范围

#include<bits/stdc++.h>
using namespace std;

int main(){
	ios::sync_with_stdio(false);
    cin.tie(0);  cout.tie(0);
    
    string str;cin>>str;
    int n=str.length();
    if(n<=8){//数据小的时候就正常暴力算
    	int sum=0;
    	for(int i=0;i<=n-1;i++){
    		sum=sum*10+str[i]-'0';
		}
		int ans=1;
		for(int i=1;;i++){
			ans=ans*i;
			if(sum==ans) cout<<i,return 0;
		}
	}
    else{//n是位数,而log大约是n-1;
    	n=n-1;
    	double ans=0;
		for(int i=1;;i++){
	    	ans+=log10(i);
	    	if(ans>=n) cout<<i,return 0;
		}
	}
    
    return 0;
}

K - Robotopia
题干说:
with at least one of each type in each group
这两组每组至少有一个机器人
但我理解成了这两组至少有一个机器人,就导致wa了好多次

还有一个坑就是当两组方程等比例的时候,即
a1x+a2y==at;
k*(a1x+a2y)==k*at;
的时候,方程是个二元一次方程,不好确定解的个数
比如x+y=2的解只有一种,x+y=100有好几个

标签:arr,Winter,Contest,int,dpb,cin,补题,dpa,dis
来源: https://blog.csdn.net/li3124992092/article/details/122507075