Cave Escape

题目链接:https://ac.nowcoder.com/acm/contest/4370/E

 

比板子稍微高级一点的题,难点在于读懂题意,和发现边的长度小于1e4使用桶排序的方法对边进行排序。

对结构体使用桶排序的方法

记录边数,前缀和得到该边长下为第几条边。再用另一个数组将其取出。

        for(int i=1;i<=cnt;i++)
        {
            tonsort[e[i].dis]++;
        }
        for(int i=tonsortnum;i>=0;i--)
        {
            tonsort[i]+=tonsort[i+1];
        }
        for(int i=1;i<=cnt;i++)
        {
        	ee[tonsort[e[i].dis]--]=e[i];
		}
#include<bits/stdc++.h>
#define ll long long
using namespace std;
int x[1000005],f[1005][1005],n,m,sr,sc,tr,tc,xx1,xx2,a,b,c,p,t;
int xxx[]={0,1},yyy[]={1,0};
int val[2000005],bcj[1000005],tt;//由于边数是2nm,所以边的数量是2000005; 
const int tonsortnum=10005;
struct edge
{
	int from,to,dis,pos;
}e[2000005];//e范围,只想右下搜边的数为n*m 
edge ee[2000005];
bool cmp(edge a,edge b)
{
	return a.dis>b.dis;
}

int find(int x)
{
	if(bcj[x]==x)return x;
	return bcj[x]=find(bcj[x]);
}
int main()
{
	ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
	cin>>t;
	for(int tt=1;tt<=t;tt++)
	{
		ll cnt=0,ecnt=0;
		cin>>n>>m>>sr>>sc>>tr>>tc;
		cin>>xx1>>xx2>>a>>b>>c>>p;
		x[1]=xx1;x[2]=xx2;
		for(int i=3;i<=n*m;i++) //n*m,题目数据范围弄错,还导致x值有问题 
		{
			x[i]=(a*x[i-1]+b*x[i-2]+c)%p;//加c呢,加c呢.. 
		}
		/*for(int i=3;i<=n*m;i++)
		{
			cout<<x[i]<<' ';
		}*/
		for(int i=1;i<=n;i++)
		{
			for(int j=1;j<=m;j++)
			{
				f[i][j]=x[(i-1)*m+j];//i-1有括号,有括号。。。 
			}
		}
		/*for(int i=1;i<=n;i++)
		{
			for(int j=1;j<=m;j++)
			{
				cout<<f[i][j]<<' ';
			}
			cout<<endl;
		}*/
/*		for(int i=1;i<=n;i++)
		{
			cout<<val[i]<<' ';
		}*/
		for(int i=1;i<=n;i++)
		{
			for(int j=1;j<=m;j++)
			{
				for(int k=0;k<2;k++)//只向右下搜 
				{//代码过于繁琐,重构
					int xx=i+xxx[k],yy=j+yyy[k];
					if(xx>=1&&yy>=1&&xx<=n&&yy<=m)//*
					{
						e[++cnt].dis=f[i][j]*f[xx][yy];
						e[cnt].from=(i-1)*m+j;
						e[cnt].to=(xx-1)*m+yy;
                        e[cnt].pos=cnt;
					}
				}
			}
		}
		/*for(int i=1;i<=cnt;i++)
		cout<<e[i].dis<<' '<<e[i].from<<' '<<e[i].to<<' '<<endl;*/
        
        int tonsort[tonsortnum]={0},toncnt=0,tontmp[tonsortnum]={0};
        /*for(int i=1;i<=cnt;i++)
        {
            cout<<e[i].dis<<' ';
        }*/
        //cout<<endl;
        for(int i=1;i<=cnt;i++)
        {
            tonsort[e[i].dis]++;
        }
        for(int i=tonsortnum;i>=0;i--)
        {
            tonsort[i]+=tonsort[i+1];
        }
        for(int i=1;i<=cnt;i++)
        {
        	ee[tonsort[e[i].dis]--]=e[i];
		}
        /*for(int i=1;i<=cnt;i++)
        {
            cout<<ee[i].dis<<' ';
        }*/
		//sort(e+1,e+cnt+1,cmp);//由于使用的是++cnt,故cnt最终的数量等于边的数量,故为e+cnt+1; 
		int cntm=0;
		for(int i=1;i<=n*m;i++)bcj[i]=i;
		for(int i=1;i<=cnt;i++)//最终边的数量并不是n*m条,而是2*n*m条,也就是cnt条 
		{
			int ff=find(ee[i].from),ft=find(ee[i].to);
			if(ff!=ft)
			{
				bcj[ff]=ft;
				ecnt+=ee[i].dis*1LL;
				cntm++;
				if(cntm==n*m-1)break;
			}
		}
		cout<<"Case #"<<tt<<": "<<ecnt<<endl;
	}
	return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值