西南民族大学第十三届程序设计竞赛题解

题目链接​​​​​​​第十三届西南民族大学程序设计竞赛(同步赛)_ACM/NOI/CSP/CCPC/ICPC算法编程高难度练习赛_牛客竞赛OJ大学ACM校赛新生赛是面向ACM/ICPC/CCPC/区域赛校队选手,巩固经典专题的编程比赛,ACM入门训练,大学ACM校队选拔比赛。https://ac.nowcoder.com/acm/contest/26524

A.《落花》&&《红衣集》。

按照题意模拟即可,两个相同美丽值的花取价值较小的,复杂度 O(n)
#include<bits/stdc++.h>

using namespace std;

typedef long long ll;

ll p[1000005],q[1000005];

int main()
{
	ll t,n,m,i,j,k;
	
	scanf("%lld",&n);
	for(i=1;i<=n-1;i++) scanf("%lld",&p[i]);
	for(i=1;i<=n-1;i++) scanf("%lld",&q[i]);
	
	p[n]=1e17;q[n]=-1e17;
	ll now=q[1],ans=p[1];
	//beati:q
	for(i=2;i<=n;i++)
	{
		if(q[i]<=now) continue;
		if((q[i+1]>q[i])||(q[i+1]==q[i]&&p[i+1]<p[i]))
		{
			now=q[i+1];
			ans+=p[i+1];
		}
		else
		{
			now=q[i];
			ans+=p[i];
		}
		i++;
	}
	
	cout<<ans;

	return 0;
}

B.留春春不住,春归人寂寞。

单源最短路板子题,O(n^2)就能过  

#include<bits/stdc++.h>

using namespace std;

typedef long long ll;

vector<ll> p[1000005],q[1000005];
ll dis[100005],vis[1000005];

int main()
{
	ll t,n,m,i,j,k,t1,t2,t3;
	
	scanf("%lld %lld",&n,&m);
	for(i=1;i<=m;i++)
	{
		scanf("%lld %lld %lld",&t1,&t2,&t3);
		{
			p[t1].push_back(t2);
			q[t1].push_back(t3);
			p[t2].push_back(t1);
			q[t2].push_back(t3);
		}
	}
	
	for(i=2;i<=n;i++) dis[i]=1e17;
	
	for(ll cnt=1;cnt<=n;cnt++)
	{
		ll mn=1e17,pos;
		for(i=1;i<=n;i++)
		{
			if(dis[i]<mn&&!vis[i])
			{
				mn=dis[i];
				pos=i;
			}
		}
		
		vis[pos]=1;
		
		for(i=0;i<(ll)p[pos].size();i++)
		{
			ll nxt=p[pos][i];
			dis[nxt]=min(dis[nxt],dis[pos]+q[pos][i]);
		}
	}
	
	ll ques;
	scanf("%lld",&ques);
	while(ques--)
	{
		scanf("%lld",&i);
		printf("%lld\n",dis[i]);
	}

	return 0;
}

C.厌风风不定,风起花萧索。

前缀和模拟,用 map 映射字符串和数字下标,复杂度 O(n*n*logn+q*logn)
#include<bits/stdc++.h>

using namespace std;

typedef long long ll;

char p[1000005];
ll q[1000005];

struct rec
{
	ll init;
	ll name;
	ll times[1005];
	ll pre[1005];
	bool operator <(const rec b)const
	{
		return name<b.name;
	}
}rc[1005];

bool cmp(rec a,rec b)
{
	return a.name<b.name;
}

ll gh(ll len)
{
	ll ret=0;
	
	for(ll i=0;i<len;i++)
	{
		ret*=27;
		ret+=p[i]-'a'+1;
	}
	return ret;
}

int main()
{
	ll t,n,m,i,j,k,namenow;
	cin>>n;
	
	for(i=1;i<=n;i++) rc[i].init=0;
	
	for(i=1;i<=n;i++)
	{
		scanf("%s",&p);
		scanf("%lld",&t);
		m=strlen(p);
		namenow=gh(m);
//		cout<<namenow<<" ";
		
		for(j=1;j<=n;j++)
		{
			if(rc[j].name==namenow||!rc[j].init)
			{
				rc[j].init=1;
				rc[j].name=namenow;
				rc[j].times[i]=t;
				break;
			}
		}
		
		for(j=0;j<=m+1;j++) p[j]=0;
	}
	
	sort(rc+1,rc+1+n,cmp);
	for(i=1;i<=n;i++)
	{
		for(j=1;j<=n;j++)
		{
			rc[i].pre[j]=rc[i].pre[j-1]+rc[i].times[j];
		}
	}
	
	/*
	for(i=1;i<=n;i++)
	{
		if(rc[i].name)
		{
			cout<<rc[i].name<<endl;
		}
	}
	*/
	
	ll ques,l,r;
	scanf("%lld",&ques);
	while(ques--)
	{
		scanf("%lld %lld %s",&l,&r,&p);
		m=strlen(p);
		namenow=gh(m);
		
		rec temp;temp.name=namenow;
		
		ll pos=lower_bound(rc+1,rc+1+n,temp)-rc;
		
		if(rc[pos].name!=temp.name)
		{printf("0\n");continue;}
		
		ll ans=rc[pos].pre[r]-rc[pos].pre[l-1];
		printf("%lld\n",ans);
		
		for(j=0;j<=m+1;j++) p[j]=0;
	}

	return 0;
}
/*
5
xyy 10
xyy 10
qx 10
xyy 10
qx 10
1
1 5 xyy
*/

 D.兴风前叹,重命花下酌。

1.错误

 2.费马大定理,显然正确

3.请注意,是s11总决赛,故是EDG战胜了DK,故错误

4.请注意,加了分号语法也是正确的,但是不推荐这么做

5.正确

6.栈的模拟,正确

7.显然错误

#include<bits/stdc++.h>

using namespace std;

typedef long long ll;
#define pi acos(-1);
ll p[1000005],q[1000005];

int main()
{
	
	cout<<"FTFTTTF";

	return 0;
}

 E.劝君尝绿醅,教人拾红萼。

本题考查转义字符

#include<bits/stdc++.h>

using namespace std;

typedef long long ll;

ll p[1000005],q[1000005];

int main()
{
	ll t,n,m,i,j,k;
	
	printf("\"xi\\nan\\min\\zu\\da\\xue,zhen\\mei!\"");
	return 0;
}

F.飘火焰焰,梨堕雪漠漠。

先排除喜爱的 k个游戏,将剩下的游戏按照时间排序,从小到大取即可。
#include<bits/stdc++.h>

using namespace std;

typedef long long ll;

ll p[1000005],q[1000005];

int main()
{
	ll t,n,m,i,j,k;
	
	cin>>n>>m>>k;
	ll ans=0;
	for(i=1;i<=n;i++) scanf("%lld",&p[i]);
	for(i=1;i<=m;i++)
	{
		scanf("%lld",&j);
		ans+=p[j];
		p[j]=1e17;
		k--;
	}
	
	sort(p+1,p+1+n);
	for(i=1;i<=k;i++) ans+=p[i];
	cout<<ans;

	return 0;
}

G.有病眼花,春风吹不落。

当构成封闭的圈时,连的那条线有个显著的特征,就是两个点一定联通,所以,一条线段连起来时,如 果两个点已经联通,则会构成闭合的圈,用并查集模拟一遍即可得到答案
#include<bits/stdc++.h>

using namespace std;

typedef long long ll;

ll father[10000005],q[1000005];

ll getfa(ll v){
	if(father[v]==v){
		return v;
	}
	father[v]=getfa(father[v]);
	return father[v];
}
ll relate(ll i,ll j){
	i=getfa(i);
	j=getfa(j);
	if(i!=j){
		father[j]=i;
		return 0;
	}
	return 1;
}

int main()
{
	ll t,n,m,i,j,k,x,y;
	char type;
	
	scanf("%d %d",&n,&m);
	
	for(i=1;i<=10000000;i++) father[i]=i;
	
	for(i=1;i<=m;i++)
	{
		scanf("%d %d %c",&x,&y,&type);
		
		if(type=='D')
		{
			if(relate(x*3001+y,(x+1)*3001+y))
			{
				printf("%lld",i);
				return 0;
			}
		}
		else
		{
			if(relate(x*3001+y,x*3001+(y+1)))
			{
				printf("%lld",i);
				return 0;
			}
		}
	}
	printf("draw");
	
	
	

	return 0;
}

H.荷池堪作镜,盈盈可鉴心。

数组瞎搞就行

#include<bits/stdc++.h>

using namespace std;
const int mod=1e9+7;
const int maxn=1e7+5;

int a[maxn];

int main()
{
    int x; cin>>x;
    a[0]=0;
    a[1]=1;
    a[2]=2;
    a[3]=3;
    for(int i=4;i<=x;++i)
        a[i]=(a[i-1]%mod+a[i-3]%mod)%mod;
    cout<<a[x]<<endl;
    
    
    
    
    return 0;
}

 I.荷香堪筑梦,鸳鸯和月寻。

判断能不能到这一秒,发现只和上一秒所在的位置有关,所以我们维护上一行能够到的所有位置,去更 新这一行能够到达的位置即可
#include<bits/stdc++.h>

using namespace std;

typedef long long ll;

char p[1005][1005];
ll q[1005][1005];
ll n,m,k;

void try1(ll x,ll y)
{
//	cout<<x<<" "<<y<<endl;
	if(x<1||x>n||y<1||y>m) return;
	if(p[x][y]=='*') return;
	q[x][y]=1;
	return;
}

int main()
{
	ll t,i,j;
	cin>>n>>m>>k;
	
	for(i=1;i<=n;i++)
	{
		scanf("%s",p[i]+1);
	}
	for(i=1;i<=n;i++)
	{
		for(j=1;j<=m;j++)
		{
			if(p[i][j]=='a') q[i][j]=1;
		}
	}
	
	for(i=n;i>1;i--)
	{
		for(j=1;j<=m;j++)
		{
			if(q[i][j])
			{
				for(ll z=j-k;z<=j+k;z++)
				{
					try1(i-1,z);
				}
			}
		}
	}
	/*
	for(i=1;i<=n;i++)
	{
		for(j=1;j<=m;j++)
		{
			cout<<q[i][j];
		}
		cout<<endl;
	}
	*/
	
	for(i=1;i<=n;i++)
	{
		ll ok=0;
		for(j=1;j<=m;j++)
		{
			if(p[i][j]!='*'&&q[i][j]) ok=1;
		}
		if(!ok)
		{
//			cout<<i;
			printf("no");
			return 0;
		}
	}
	printf("yes");

	return 0;
}
/*
3 4 1
...*
***.
..a.
*/

J.荷香莫深湎,终付秋风落。

注意到只要:的下一个是w即可

#include<bits/stdc++.h>

using namespace std;

int main()
{
    int ans=0;
    string s; 
    while(cin>>s){
        for(int i=0;i<s.size();++i){
            if(s[i]==':'&&s[i+1]=='w') ++ans;
        }
    }
    cout<<ans<<endl;
    
    
    
    return 0;
}

K.荷香竟深湎,永待盛夏陌。

观察可知,每一个石块可以通过 4 步以内和后面一个石块数字相同,当两个相邻数字相同时,可以让这两 个石块和后一个石块数字相同,三个相同时,可以让这三个石块和第四个石块数字相同,可知16 步以内 必然可以解出来。
#include<bits/stdc++.h>

using namespace std;

typedef long long ll;

ll p[1000005],q[1000005];

int main()
{
	ll t,n,m,i,j,k,l,z;
	cin>>t;
	while(t--)
	{
		scanf("%lld %lld %lld %lld",&p[1],&p[2],&p[3],&p[4]);
		
		for(i=0;i<4;i++)
		for(j=0;j<4;j++)
		for(k=0;k<4;k++)
		for(l=0;l<4;l++)
		{
			q[1]=p[1]+l+i+j;
			q[2]=p[2]+i+j+k;
			q[3]=p[3]+j+k+l;
			q[4]=p[4]+k+l+i;
			
			for(z=1;z<=4;z++)
			{
				q[z]%=4;
				if(!q[z]) q[z]=4;
			}
			
			if(q[1]==q[2]&&q[2]==q[3]&&q[3]==q[4])
			{
				printf("%lld\n",i+j+k+l);
				while(i--) printf("1 ");
				while(j--) printf("2 ");
				while(k--) printf("3 ");
				while(l--) printf("4 ");
				if(i+j+k+l) printf("\n");
				goto ED;
			}
		}

		ED:;



	}

	return 0;
}

L.相思子肯来,约在莲花岸。

暴力枚举计算距离即可。
#include<bits/stdc++.h>

using namespace std;

typedef long long ll;

struct xxx
{
	ll x;
	ll y;
	ll type;
}me[100],enemy[100];
ll cnt1=0,cnt2=0;

ll calc(xxx a,xxx b)
{
	return (b.x-a.x)*(b.x-a.x)+(b.y-a.y)*(b.y-a.y);
}

int main()
{
	ll t,n,m,i,j,k;
	scanf("%lld %lld",&n,&m);
	for(i=1;i<=n;i++)
	{
		++cnt1;
		scanf("%lld %lld %lld",&me[i].x,&me[i].y,&me[i].type);
	}
	for(i=1;i<=m;i++)
	{
		++cnt2;
		scanf("%lld %lld %lld",&enemy[i].x,&enemy[i].y,&enemy[i].type);
	}
	
	for(i=1;i<=n;i++)
	{
		ll now,pos;
		if(me[i].type==1) now=-1e17;
		else now=1e17;
		
		for(j=1;j<=m;j++)
		{
			if(calc(me[i],enemy[j])>now&&me[i].type==1)
			{
				now=calc(me[i],enemy[j]);
				pos=j;
			}
			if(calc(me[i],enemy[j])<now&&me[i].type!=1)
			{
				now=calc(me[i],enemy[j]);
				pos=j;
			}
		}
		printf("%lld ",pos);
	}
	printf("\n");
	for(i=1;i<=m;i++)
	{
		ll now,pos;
		if(enemy[i].type==1) now=-1e17;
		else now=1e17;
		
		for(j=1;j<=n;j++)
		{
			if(calc(enemy[i],me[j])>now&&enemy[i].type==1)
			{
				now=calc(enemy[i],me[j]);
				pos=j;
			}
			if(calc(enemy[i],me[j])<now&&enemy[i].type!=1)
				{
					now=calc(enemy[i],me[j]);
					pos=j;
				}
		}
		printf("%lld ",pos);
	}

	return 0;
}

M.潇潇日暮时,掠水鸳鸯散。

01背包板子

#include<bits/stdc++.h>

using namespace std;

typedef long long ll;

ll p[1000005],q[1000005];

ll s[2005];

int main()
{
	ll t,n,m,i,j,k;
	
	cin>>n>>m;
	
	s[0]=0;
	for(i=1;i<=m;++i)
	{
		scanf("%lld %lld",&p[i],&q[i]);
		for(j=1000;j>=0;j--)
		{
			s[j+p[i]]=max(s[j+p[i]],s[j]+q[i]);
		}
	}
	
	cout<<s[n];

	return 0;
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

只微

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值