“科大讯飞杯”第十七届同济大学程序设计预选赛暨高校网络友谊赛题解

A张老师和菜哭武的游戏(扩展欧几里得)

题解:对于ax+by=c 存在整数解x与y,需要gcd(a,b)是c的因子。那么这题给出了a,b,直接求解gcd即可,用n除掉gcd就是可以拿走的数,再对这个数判断奇偶即可。

#include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdio>
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=1e5+5;
void io() { ios::sync_with_stdio(0);cin.tie(0);cout.tie(0); }


int main() {
	int test=1; scanf("%d",&test);
	while(test--) {
		int n,a,b;
		scanf("%d%d%d",&n,&a,&b);
        int x=__gcd(a,b);
        x=n/x;
        if(x&1) puts("Yes");
        else puts("No");
	}


	return 0;
}

B伤害计算

题解:对x面骰子掷n个,则其期望值为n*(x+1)/2;接下来就是对字符串的处理

#include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdio>
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=2e5+5;
void io() { ios::sync_with_stdio(0);cin.tie(0);cout.tie(0); }

//int a[maxn],n,t;
//pair<int,int> b[maxn];
//int s[maxn],sum[maxn],l[maxn],r[maxn];
int main() {
	int test=1; 
	while(test--) {
		double ans=0;
		string s; cin>>s;
		int a=0,b=0,flag=0;
		for(int i=0;i<s.size();i++) {
			if(s[i]=='d') flag=1;
			else if(s[i]=='+') {
				if(b!=0) ans+=1.0*a*(b+1)*1.0/2.0;
				else ans+=a;
				a=b=0; flag=0;
			} else if(flag==0) {
				a=a*10+s[i]-'0';
				b=0;
			} else{
				b=b*10+s[i]-'0';
			}
		}
		if(b==0) ans+=a;
		else ans+=1.0*a*(b+1)*1.0/2.0;
		double x=(int)ans;
		if(x==ans) cout<<(int)ans<<endl;
		else printf("%.1f\n",ans);
	}


	return 0;
}

C.张老师的旅行

题解:

对于出发点mid,我们把两侧景点分开为左右两个结合,分别求出其到出发点的距离,,这样我们可以通过 dp 来解决,我们设状态 dp[l][r][0]表示终点落在 左边集合的 ,dp[l][r][1]同理终点落在 右边 上,状态转移为:
dp[i][j][0]=min(dp[i−1][j][0]+b[i].l−b[i−1].l,dp[i−1][j][1]+c[j].l+b[i].l);
dp[i][j][1]=min(dp[i][j−1][1]+c[j].l−c[j−1].l,dp[i][j−1][0]+c[j].l+b[i].l);
那么答案就是 min(dp[cnt1][cnt2][0],f[cnt1][cnt2][1])
#include <bits/stdc++.h>
using namespace std;
void io() { ios::sync_with_stdio(0);cin.tie(0);cout.tie(0); }
struct node{
	int l,t;
	bool operator<(const node &x) const {
		return l<x.l;
	}
}a[1100],b[1100],c[1100];
int n,cnt1,cnt2,mid;
int dp[1100][1100][2];
int main() {
	io();
	cin>>n;
	for(int i=1;i<=n;i++) cin>>a[i].l;
	for(int i=1;i<=n;i++) cin>>a[i].t;
	sort(a+1,a+1+n);
	for(int i=1;i<=n;i++)
		if(a[i].t==0) mid=i;
	for(int i=mid+1;i<=n;i++) cnt2++,c[cnt2].l=a[i].l-a[mid].l,c[cnt2].t=a[i].t;
	for(int i=mid-1;i>=1;i--) cnt1++,b[cnt1].l=a[mid].l-a[i].l,b[cnt1].t=a[i].t;
	memset(dp,0x3f,sizeof(dp));
	dp[0][0][1]=dp[0][0][0]=0;
	for(int i=0;i<=cnt1;i++){
		for(int j=0;j<=cnt2;j++) {
			if(i>=1) dp[i][j][0]=min(dp[i-1][j][0]+b[i].l-b[i-1].l,dp[i-1][j][1]+c[j].l+b[i].l);
			if(j>=1) dp[i][j][1]=min(dp[i][j-1][0]+b[i].l+c[j].l,dp[i][j-1][1]+c[j].l-c[j-1].l);
			if(dp[i][j][0]>b[i].t&&dp[i][j][1]>c[j].t){
				cout<<-1<<endl;
				return 0;
			}
		}
	}
	cout<<min(dp[cnt1][cnt2][1],dp[cnt1][cnt2][0])<<endl;
	return 0;
}

D车辆调度

题解:注意到:地图大小10*10,车辆最多有4个,那么直接暴力dfs跑一遍即可。

#include <cstring>
#include <cstdio>
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=2e5+5;
void io() { ios::sync_with_stdio(0);cin.tie(0);cout.tie(0); }
char mp[12][12];
int m,n,k,flag;
int nex[4][2]={
   
   {0,-1},{0,1},{1,0},{-1,0}};

void dfs(int num) {
	if(flag || num>=k) return;
	for(int i=1;i<=n;i++)
		for(int j=1;j<=m;j++)
			if(mp[i][j]=='R') {
				for(int i1=0;i1<4;i1++) {
					int x=i+nex[i1][0],y=j+nex[i1][1];
					while(x>=1&&x<=n&&y>=1&&y<=m&&mp[x][y]!='R'&&mp[x][y]!='X'){
						x+=nex[i1][0],y+=nex[i1][1];
					}
					x-=nex[i1][0],y-=nex[i1][1];
					if(mp[x][y]=='D') {
						flag=1; return;
					}
					swap(mp[x][y],mp[i][j]);
					dfs(num+1);
					swap(mp[x][y],mp[i][j]);
				}
			}
}
int main() {
	cin>>m>>n>>k;
	for(int i=1;i<=n;i++)
	for(int j=1;j<=m;j++) cin>>mp[i][j];
	dfs(0);
	if(flag) puts("YES");
	else puts("NO");
	return 0;
}

F排列计算(差分和前缀和)

题解:对每一个位置我们设置权重,选取一个区间[l,r],则对区间内的位置权重加1,对差分数组s,s[l]++,s[r+1]--;最后再对差分数组求前缀和,排序后按权重大小分配值。

#include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdio>
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=2e5+5;
void io() { ios::sync_with_stdio(0);cin.tie(0);cout.tie(0); }

ll a[maxn],n,t;
pair<ll,ll> b[maxn];
ll s[maxn],sum[maxn],l[maxn],r[maxn];
int main() {
	int test=1; 
	while(test--) {
		scanf("%lld%lld",&n,&t);
		for(int i=1;i<=t;i++){
			scanf("%lld%lld",&l[i],&r[i]);
			s[l[i]]++,s[r[i]+1]--;
		}
		int num=0;
		
		for(int i=1;i<=n;i++) {
			num+=s[i];
			b[i].first=num;
			b[i].second=i;
		}
		sort(b+1,b+1+n);
		int x=1;
		for(int i=1;i<=n;i++){
			a[b[i].second]=x++;
		}
		for(int i=1;i<=n;i++){
			sum[i]=sum[i-1]+a[i];
		}
		ll ans=0;
		for(int i=1;i<=t;i++) {
			ans+=sum[r[i]]-sum[l[i]-1];
		}
		printf("%lld\n",ans);
	}


	return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_44132777/article/details/106050126