2021-10-05模拟赛

本文通过四个编程题目,分别探讨了SPFA寻找最短路径的双向BFS实现、国王游戏的贪心排序策略、书柜尺寸问题的动态规划解决方案以及海底珍珠串的简单暴力求解。代码中涵盖了高精度计算、排序优化和不同算法的应用。
摘要由CSDN通过智能技术生成


1、寻找道路

链接: 洛谷P2296
算法思路:SPFA找最短路,双向BFS。

#include<bits/stdc++.h>
using namespace std;
const int maxv=100001;
const int INF=1e9; 
vector<int> g[maxv];
vector<int> fg[maxv];
int d[maxv],n,m;
bool v[maxv],can[maxv];
void SPFA(int s,int t){
	fill(d,d+maxv,INF);
	fill(v,v+maxv,0);
	fill(can,can+maxv,0);
	queue<int> q1;
	queue<int> q2;
	q1.push(s);
	q2.push(t);
	can[t]=true;
	d[s]=0;
	while(!q2.empty()){
		int u=q2.front();
		q2.pop();
		if(!can[u]){
			can[u]=true;
			int a=g[u].size();
			for(int i=0;i<a;i++){
				if(!can[g[u][i]])	can[u]=false;
			}
		}
		if(can[u]&&!v[u]){
			v[u]=true;
			int a=fg[u].size();
			for(int i=0;i<a;i++){
				q2.push(fg[u][i]);
			}
		}
	}
	fill(v,v+maxv,0);
	v[s]=true;
	while(!q1.empty()){
		int u=q1.front();
		q1.pop();
		v[u]=false;
		int a=g[u].size();
		for(int j=0;j<a;j++){
			int w=g[u][j];
			if(d[u]+1<d[w]&&can[w]){
				d[w]=d[u]+1;
				if(!v[w]){
					q1.push(w);
					v[w]=true;
				}
			}
		}
	}
}
int main(){
	scanf("%d%d",&n,&m);
	for(int i=1;i<=m;i++){
		int a,b;
		scanf("%d%d",&a,&b);
		g[a].push_back(b);
		fg[b].push_back(a);
	}
	int s,t;
	scanf("%d%d",&s,&t);
	SPFA(s,t);
	if(d[t]==INF)	printf("-1\n");
	else	printf("%d\n",d[t]); 
	return 0; 
}

你这代码它保过吗
估分:60分
实际:10分
不保过
感想:总有无知的蒟蒻,敢于迷失在自己的BFS中。
有些代码,写着写着就成玄学了
订正代码
最后再说一遍
最短路要优化了
[Made in BFS]

#include<bits/stdc++.h>
using namespace std;
bool inroad[10010],can[10010];
int dis[10010]; 
vector<int>side[10010];
vector<int>edis[10010];
int main()
{
    int n,m,a,b,s,t;
    cin>>n>>m;
    for(int i=1;i<=m;i++)
    {
        cin>>a>>b;
        side[a].push_back(b);
        edis[b].push_back(a);
    }
    cin>>s>>t;
    can[t]=1;
    queue<int>que; 
    que.push(t);
    while(!que.empty()){
        int now=que.front();
        que.pop();
        for(int i=edis[now].size()-1;i>=0;i--)
        {
            int to=edis[now][i];
            if(!can[to])
            {
                que.push(to);   
                can[to]=1;
            }
        }
    }
    if(!can[s]){
        cout<<"-1";
        return 0;
    }
    for(int i=1;i<=n;i++){
        if(can[i])
        {
            inroad[i]=1;
            for(int j=side[i].size()-1;j>=0;j--){
                int to=side[i][j];
                if(!can[to]){
                    inroad[i]=0;
                    break;
                }
            }
        }
    }
    if(!inroad[s]){
    	cout<<"-1";
    	return 0;
        }
    dis[s]=1;que.push(s);
    while(!que.empty()){
        int now=que.front();
        que.pop();
        if(now==t){
            cout<<dis[t]-1;
            return 0;
        }
        for(int i=side[now].size()-1;i>=0;i--){
            int to=side[now][i];
            if(inroad[to]&&!dis[to])
            {
                dis[to]=dis[now]+1;
                que.push(to);
            }
        }
    }
    cout<<"-1";
    return 0;
}

2、 国王游戏

链接:洛谷P1080
算法:贪心排序
可能要用的:高精度
(这辈子都不可能用高精的,只能靠着longlong混混日子。不是)
代码

#include<bits/stdc++.h>
using namespace std;
struct node{
	long long int l,r,x;
}g[1005];
bool cmp(node a,node b){
	return a.x<b.x;
}
int main(){
	long long int ans=0,sum,n,a,b;
	scanf("%lld%lld%lld",&n,&a,&b);
	for(int i=1;i<=n;i++){
		scanf("%lld%lld",&g[i].l,&g[i].r);
		g[i].x=g[i].l*g[i].r;
	}
	sort(g+1,g+n+1,cmp);
	sum=a;
	for(int i=1;i<=n;i++){
		ans=max(ans,sum/g[i].l);
		sum*=g[i].r;
	}
	printf("%lld",ans);
	return 0;
}

估分:60分
实际:零分。。。
复查,我左右手反了。。。
再测60分。
感想:phthon yygjds

#include<bits/stdc++.h>
using namespace std;
const int MAX_SIZE = 10100;
struct node{
	int l,r;
	long long int x;
}g[1005];
bool cmp(node a,node b) {
    return a.x<b.x;
}
struct Int {
	int len, n[MAX_SIZE];
	void Set(int l) {
		len = l;
		for(int i = 1; i <= len; i ++) n[i] = 0;
	}
	Int(long long x = 0) {
		len = 0;
		do {
			n[++ len] = x % 10;
			x /= 10;
		} while(x);
	}
	bool operator < (const Int b) {
		if(len != b.len) return len < b.len;
		for(int i = len; i; i --)
			if(n[i] != b.n[i]) return n[i] < b.n[i];
		return false;
	}
	Int operator * (Int b) {
		Int ans; ans.Set(len + b.len);
		for(int i = 1; i <= len; i ++) {
			for(int j = 1; j <= b.len; j ++) {
				ans.n[i + j - 1] += n[i] * b.n[j];
				ans.n[i + j] += ans.n[i + j - 1] / 10;
				ans.n[i + j - 1] %= 10;
			}
		}
		while(!ans.n[ans.len] && ans.len > 1) ans.len --;
		return ans;
	}
	Int operator / (const int &b) { //除以低精  
     	    if(*this < Int(b)) return Int(0LL);  
     	    Int ans; ans.len = len;  
     	    int r = 0;  
     	    for(int i = ans.len; i; i --) {  
     		r = r * 10 + n[i];  
     		ans.n[i] = r / b;  
          	r %= b;  
        }  
            while(ans.len > 1 && !ans.n[ans.len]) ans.len --;  
            return ans;  
        }
	void print() {
		for(int i = len; i; i --) 
			printf("%d", n[i]);
		printf("\n");
	}
};
int main(){
	int n,a,b;
	scanf("%d%d%d",&n,&a,&b);
	for(int i=1;i<=n;i++){
		scanf("%d%d",&g[i].l,&g[i].r);
		g[i].x=g[i].l*g[i].r;
	}
	sort(g+1,g+n+1,cmp);
	Int sum(a);
	Int aws(1);
	for(int i=1;i<=n;i++){
		if(aws<(sum/g[i].r))	aws=(sum/g[i].r);
		sum=sum*g[i].l;
	}
	aws.print();
	return 0;
}

3、书柜的尺寸

链接:洛谷P2160
算法:排序
可能的解法:动规
没写的出来(紫题好耶)
跳转隔壁题解 懒.jpg
订正代码

#include <bits/stdc++.h>
using namespace std;
#define maxn 2105
#define INF 0x3f
struct Node{
    int h,t;
}a[80];
bool cmp(Node a,Node b){return a.h>b.h;}
int f[2][maxn][maxn],n,sum[80];
int main()
{
    scanf("%d",&n);
    for (int i=1;i<=n;i++)scanf("%d%d",&a[i].h,&a[i].t);
    sort(a+1,a+1+n,cmp);
    sum[1]=a[1].t;
    for (int i=2;i<=n;i++) sum[i]=sum[i-1]+a[i].t;//前缀和
    memset(f,INF,sizeof(f));
    f[1][0][0]=f[0][0][0]=0;
    int now,pre;
    for (int i=1;i<=n;i++)
    {
        now=i&1;pre=now^1;
        memset(f[now],INF,sizeof(f[now]));
        for (int j=0;j<=sum[i];j++)
             for (int k=0;k<=sum[i];k++)
             if (f[pre][j][k]!=INF)
             {
                  f[now][j+a[i].t][k]=(j==0)? min(f[now][j+a[i].t][k],f[pre][j][k]+a[i].h):min(f[now][j+a[i].t][k],f[pre][j][k]);
                  f[now][j][k+a[i].t]=(k==0)? min(f[now][j][k+a[i].t],f[pre][j][k]+a[i].h):min(f[now][j][k+a[i].t],f[pre][j][k]);
                  f[now][j][k]=(sum[i-1]-j-k==0)?min(f[now][j][k],f[pre][j][k]+a[i].h):min(f[now][j][k],f[pre][j][k]);
             }
    }
    long long ans=1<<30;
    for (int i=1;i<=sum[n];i++)
        for (int j=1;j<=sum[n];j++)
        if (sum[n]-i-j)ans=min(ans,(long long)max(max(i,j),sum[n]-i-j)*(long long)f[now][i][j]);    
    cout<<ans<<endl;
    return 0;
}
(转载)

4、海底珍珠串

算法:暴力 真实ing
可能的解法:动规
你看这个代码,它超逊的啦。

#include<bits/stdc++.h>
using namespace std;
int main(){
	int n,a[150],step=0;
	memset(a,0,sizeof(a));
	scanf("%d",&n);
	string r;
	cin>>r;
	for(int i=0;i<n;i++)
		a[int(r[i])]++;
	for(int i=1;i<=128;i++)
		if(a[i]%2!=0)	step++;	
	if(step<2)	printf("1");
	else	printf("%d",step);
	return 0;
}

估不出来。。。
实际:10分
感想:动规你太美(nan)


总分:80?/400
整场比赛的总结:一言以蔽之,逊。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值