计蒜客信息学 3 月普及组模拟赛(B 找规律 C拓扑dp D二分+bfs)

题目链接

做出了A,C,D不会B

A水题

B积木游戏

做法:

喵了个咪的  还不能用java大整数,因为只除了一个个位数的整数,那就手撸c++大数除数吧

参考代码来自:传送门

#include<bits/stdc++.h>
using namespace std;
char a1[1000010];
int a[1000010], lena, i, res[1000010], s;//res[110]存储每一位商 s表示余数 
int main(){
	long long n;
	for(int j=1; j<=3; j++){
		gets(a1);
		lena=strlen(a1);
		//高精求余数 
		for(i=0; i<lena; i++)//将a1字符串数组按照顺序存储在a[i]整形数组中 
			a[i]=a1[i]-'0';
		s=a[0];//将余数初始化 
		for(i=1; i<lena; i++)//for循环输出找到每一位商,和最后的余数 
		{
			int aa=s*10+a[i];//aa表示除数 
			res[i]=aa/3;//取得商 
			s=aa%3;//取得余数 
		}
		s %= 3;
		//判断余数 
		if(s == 0){
			printf("Hua will win.\n");
		}else if(s == 1 || s == 2){
			printf("Ming will win.\n");
			printf("%d\n",s);
		}
	}
	return 0;
}

C-箱子

表示以前做过一模一样的,每个箱子有六种形态,然后n方  dp一下就可以了

dp[i]代表 最后一个是i这个箱子的最大层数

#include<bits/stdc++.h>
#define rep(i,a,b) for(int i=a;i<=(b);++i)
#define mem(a,x) memset(a,x,sizeof(a))
#define pb push_back
#define pi pair<int, int>
#define mk make_pair
using namespace std;
typedef long long ll;
ll gcd(ll a,ll b) { return b?gcd(b,a%b):a;}
const int N=1e3+10;
int n,len;
struct node
{
    int x,y;
    ll h;
}a[N],dp[N];
bool cmp(node a,node b)
{
    if(a.x!=b.x) return a.x<b.x;
    if(a.y!=b.y) return a.y<b.y;
    return a.h<b.h;
}
int cal(int x,int y,node a)
{
    if(a.x<x&&a.y<y) return 1;
    if(a.x<y&&a.y<x) return 1;
    return 0;
}
int main()
{
	scanf("%d",&n);
	rep(i,1,n){
        int x,y,z;
        cin>>x>>y>>z;
        a[++len]={x,y,z};
        a[++len]={x,z,y};
        a[++len]={y,x,z};
        a[++len]={y,z,x};
        a[++len]={z,x,y};
        a[++len]={z,y,x};
	}
	sort(a+1,a+1+len,cmp);
	ll ans=0;
	for(int i=1;i<=len;++i){
        for(int j=0;j<i;++j){
            if(cal(a[i].x,a[i].y,dp[j])){
                if(dp[i].h<dp[j].h+a[i].h){
                    dp[i].h=dp[j].h+a[i].h;
                    dp[i].x=a[i].x;
                    dp[i].y=a[i].y;
                    ans=max(ans,dp[i].h);
                }
            }

        }
	}
	printf("%d\n",ans);
}

D-明跑

二分思路很好想,二分这个威胁度,将怪兽周围长度全部设置不能通过,最后bfs一下能否到达终点即可

#include<bits/stdc++.h>
#define rep(i,a,b) for(int i=a;i<=(b);++i)
#define mem(a,x) memset(a,x,sizeof(a))
#define pb push_back
#define pi pair<int, int>
#define mk make_pair
using namespace std;
typedef long long ll;
ll gcd(ll a,ll b) { return b?gcd(b,a%b):a;}
const int N=1e3+10;
int vis[N][N],n,m,len,vs[N][N];
struct node
{
    int x,y,w;
}a[N*N];
int dir[4][2]={1,0,0,1,-1,0,0,-1};
int bfs()
{
    memset(vs,0,sizeof(vs));
    queue<node>que;
    que.push({1,1,0});
    vs[1][1]=1;
    while(que.size()){
        node now=que.front();que.pop();
        if(now.x==n&&now.y==m) return 1;
        for(int i=0;i<4;++i){
            int x=now.x+dir[i][0];
            int y=now.y+dir[i][1];
            if(x<1||y<1||x>n||y>m) continue;
            if(vis[x][y])continue;
            if(vs[x][y])continue;
            vs[x][y]=1;
            que.push({x,y,0});

        }
    }
    return 0;
}
int cal(int mid)
{
    queue<node>que;
    memset(vis,0,sizeof(vis));
    for(int i=1;i<=len;++i){
        que.push({a[i].x,a[i].y,mid});
        vis[a[i].x][a[i].y]=mid;
    }
    while(que.size()){
        node now=que.front();que.pop();
        if(now.w==1) continue;
        for(int i=0;i<4;++i){
            int x=now.x+dir[i][0];
            int y=now.y+dir[i][1];
            if(x<1||y<1||x>n||y>m) continue;
            if(now.w-1>vis[x][y]){
                vis[x][y]=now.w-1;
                que.push({x,y,vis[x][y]});
            }
        }
    }
    return bfs();
}
int main()
{
	cin>>n>>m;
	rep(i,1,n)rep(j,1,m){int x;scanf("%d",&x);if(x==1) a[++len]={i,j};}

	rep(i,1,len) vis[a[i].x][a[i].y]=1;

	if(vis[1][1]||vis[n][m]||!bfs()){
        printf("0");
        return 0;
	}

	int l=1,r=n+m,ans=0;
	while(l<=r){
        int mid=l+r>>1;
        if(cal(mid)) l=mid+1,ans=mid;
        else r=mid-1;
	}
	printf("%d\n",ans);
}
发布了498 篇原创文章 · 获赞 66 · 访问量 4万+

猜你喜欢

转载自blog.csdn.net/qq_41286356/article/details/104867765