zoukankan      html  css  js  c++  java
  • 20201121 模拟赛总结

    题目PDF,提取码 iqmz

    (100+60+15=175 ext{pts})

    打了三个暴力居然苟了个 rk1。。不可思议

    T1

    原题:洛谷 P1292

    由裴蜀定理,可知第一问答案为 (gcd(a,b))。于是第二问答案就变成了求满足 (ax+by=gcd(a,b))(x,y),exgcd 求解然后二分调整一下答案使得答案满足条件即可。

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    using namespace std;
    #define int long long
    int exgcd(int a,int b,int &x,int &y)
    {
    	if(b==0)
    	{
    		x=1;y=0;
    		return a;
    	}
    	int ans=exgcd(b,a%b,x,y);
    	int t=x;
    	x=y;
    	y=t-a/b*y;
    	return ans;
    }
    signed main()
    {
    	freopen("pour.in","r",stdin);
    	freopen("pour.out","w",stdout);
    	int a,b,x,y;
    	scanf("%lld %lld",&a,&b);
    	if(b>a) swap(a,b);
    	if(a%b==0)
    	{
    		printf("%lld
    0 1",b);
    		return 0;
    	}
    	int gg;
    	printf("%lld
    ",gg=exgcd(a,b,x,y));
    	int ans=0,l=-1e9,r=1e9;
    	int ml=b/gg,mr=a/gg;
    	while(l<=r)
    	{
    		int mid=(l+r)/2;
    		if(x+mid*ml<=0 && y-mid*mr>0) 
    		{
    			ans=mid;
    			l=mid+1;
    		}
    		else r=mid-1;
    	}
    	x=x+ans*ml;y=y-ans*mr;
    	printf("%lld %lld",-x,y);
    	return 0;
    }
    

    T2

    在洛谷上传了数据,可以点这里提交。

    60pts

    (mathcal O(n^2m^2)) 枚举左上角和右下角,二位前缀和预处理然后 (mathcal O(1)) 判断是否可行。

    PS:这个做法被 lht 加上几个剪枝卡过去了……而且跑的比正解还快……

    100pts

    三重循环,第一重枚举长方形的上面的边,第二重枚举下面的边,第三重从左到右扫一遍看看能得到的最大左右距离(可以通过前缀和实现)。

    时间复杂度 (mathcal O(n^2 m))

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    using namespace std;
    const int N=400;
    char s[N+10][N+10];
    int sum[N+10][N+10];
    int main()
    {
    	int n,m;
    	scanf("%d %d",&n,&m);
    	for(int i=1;i<=n;i++) scanf("%s",s[i]+1);
    	for(int i=1;i<=n;i++) 
    	{
    		for(int j=1;j<=m;j++)
    		{
    			sum[i][j]=sum[i-1][j];
    			sum[i][j]+=(s[i][j]=='X'); 
    		}
    	}
    //	for(int i=1;i<=n;i++)
    //	{
    //		for(int j=1;j<=m;j++) printf("%d ",sum[i][j]);
    //		putchar('
    ');
    //	}
    	int ans=0;
    	for(int i=1;i<=n;i++)
    	{
    		for(int j=i;j<=n;j++)
    		{
    			int mx=0,cnt=0;
    			for(int k=1;k<=m;k++)
    			{
    				if(sum[j][k]-sum[i-1][k]==0) cnt++;
    				else cnt=0;
    				mx=max(mx,cnt);
    			}
    			if(mx) ans=max(ans,(j-i+1)*2+mx*2);
    		}
    	}
    	printf("%d",ans-1);
    	return 0;
    }
    

    T3

    原题:bzoj 2143

    吐槽一波题面,Input 里 (A_{i,j})(B_{i,j}) 写反了。。

    首先暴力连边肯定是不行的,会 MLE+TLE。

    考虑拆点。按照每个点 ((x,y)) 的弹射能力 (B_{x,y})((x,y)) 拆成 (B_{x,y}+1) 个点,记作 ((x,y,0),(x,y,1),cdots,(x,y,B_{x,y})),第三维的意义是到达点 ((x,y)) 的时候还剩多少能量,这里能量的的意思是每到达一个点 ((i,j)),能量就会增加 (B_{i,j}),跳了多少距离能量就相应地减少多少。Dijkstra 过程中每次到 ((x,y,0)) 就只能考虑跳到 ((x,y,B_{x,y})),其他情况考虑向上、向下、向左、向右和原地不动即可。

    这题套路有点类似 10 月 17 日模拟赛的 T2,但又没做出来 /kk

    #include<iostream>
    #include<cstring>
    #include<algorithm>
    #include<cstdio>
    #include<queue>
    using namespace std;
    const int INF=0x3f3f3f3f;
    inline void read(int &x)
    {
    	x=0; int f=1;
    	char c=getchar();
    	while(c<'0' || c>'9')
    	{
    		if(c=='-') f=-1;
    		c=getchar();
    	}
    	while(c>='0' && c<='9')
    	{
    		x=(x<<1)+(x<<3)+(c^48);
    		c=getchar();
    	}
    	x*=f;
    }
    const int nxt[5][2]={{0,1},{1,0},{0,-1},{-1,0},{0,0}};
    int n,m;
    struct node
    {
    	int x,y,d,en; //distance, energy
    	node() {}
    	node(int tx,int ty,int te,int td) {x=tx;y=ty;d=td;en=te;}
    	bool operator < (const node &x) const {return d>x.d;}
    }; //priority_queue
    const int N=150;
    int dis[N+10][N+10][N*2+10];
    int a[N+10][N+10],b[N+10][N+10];
    bool vis[N+10][N+10][N*2+10];
    inline void dij(int Sx,int Sy) // S -> T
    {
    	memset(vis,0,sizeof(vis));
    	priority_queue<node> que;
    	memset(dis,0x3f,sizeof(dis));
    	dis[Sx][Sy][b[Sx][Sy]]=a[Sx][Sy];
    	que.push(node(Sx,Sy,b[Sx][Sy],a[Sx][Sy]));
    	while(!que.empty())
    	{
    		node head=que.top(); que.pop();
    		// printf("head:(%d, %d), %d
    ",head.x,head.y,head.en);
    		if(vis[head.x][head.y][head.en]) continue;
    		vis[head.x][head.y][head.en]=true;
    		if(head.en>0)
    		{
    			for(int k=0;k<=4;k++)
    			{
    				int tx=head.x+nxt[k][0],ty=head.y+nxt[k][1];
    				if(tx<1 || tx>n || ty<1 || ty>m) continue;//dis[][][]:(x, y)  energy: z
    				if(dis[head.x][head.y][head.en]<dis[tx][ty][head.en-1])
    				{
    					dis[tx][ty][head.en-1]=dis[head.x][head.y][head.en];
    					que.push(node(tx,ty,head.en-1,dis[tx][ty][head.en-1]));
    				}
    			}
    		}
    		else
    		{
    			if(dis[head.x][head.y][0]+a[head.x][head.y]<dis[head.x][head.y][b[head.x][head.y]])
    			{
    				dis[head.x][head.y][b[head.x][head.y]]=dis[head.x][head.y][0]+a[head.x][head.y];
    				que.push(node(head.x,head.y,b[head.x][head.y],dis[head.x][head.y][b[head.x][head.y]]));
    			}
    		}
    	}
    }
    //a[][]: cost
    //b[][]: energy
    typedef pair<int,int> pii;
    int main()
    {
    	freopen("zhber.in","r",stdin);
    	freopen("zhber.out","w",stdout);
    	read(n);read(m);
    	for(int i=1;i<=n;i++)
    		for(int j=1;j<=m;j++)
    		{
    			read(b[i][j]);
    			b[i][j]=min(b[i][j],n+m-2);
    		}
    	for(int i=1;i<=n;i++)
    		for(int j=1;j<=m;j++)
    			read(a[i][j]);
    	pii xx,yy,zz;
    	read(xx.first);read(xx.second);read(yy.first);read(yy.second);read(zz.first);read(zz.second);
    	int d[3][3];memset(d,0,sizeof(d));
    	// printf("(%d, %d), (%d, %d), (%d, %d)
    ",xx.first,xx.second,yy.first,yy.second,zz.first,zz.second);
    	dij(xx.first,xx.second);d[0][1]=dis[yy.first][yy.second][0];d[0][2]=dis[zz.first][zz.second][0];
    	dij(yy.first,yy.second);d[1][0]=dis[xx.first][xx.second][0];d[1][2]=dis[zz.first][zz.second][0];
    	dij(zz.first,zz.second);d[2][0]=dis[xx.first][xx.second][0];d[2][1]=dis[yy.first][yy.second][0];
    	int X=d[1][0]+d[2][0],Y=d[0][1]+d[2][1],Z=d[0][2]+d[1][2];
    	// printf("d[][]:
    ");
    	// for(int i=0;i<3;i++)
    	// {
    	// 	for(int j=0;j<3;j++) printf("%d ",d[i][j]);
    	// 		putchar('
    ');
    	// }
     	if(X>=INF && Y>=INF && Z>=INF) puts("NO");
    	else
    	{
    		if(X<=Y && X<=Z) printf("X
    %d",X);
    		else if(Y<=X && Y<=Z) printf("Y
    %d",Y);
    		else if(Z<=X && Z<=Y) printf("Z
    %d",Z);
    	}
    	return 0;
    }
    
  • 相关阅读:
    数据字典的设计
    2005年9月全国计算机等级考试二级C语言笔试试题
    2005年4月全国计算机等级考试二级C语言笔试试题
    2004年4月全国计算机等级考试二级C语言笔试试题
    2003年9月全国计算机等级考试二级C语言笔试试卷
    2006年4月全国计算机等级考试二级C语言笔试试题
    2004年9月全国计算机等级考试二级C语言笔试试题
    2006年9月全国计算机等级考试二级C笔试真题及参考答案
    2003年4月全国计算机等级考试二级C语言笔试试题
    2002年9月全国计算机等级考试二级C语言笔试试题
  • 原文地址:https://www.cnblogs.com/juruo-zzt/p/14015466.html
Copyright © 2011-2022 走看看