UCF Local Programming Contest 2017

A 直接算就好了

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
ll a,b,n,x;
int main()
{
	cin>>a>>b>>n;
	while(n--)
	{
		cin>>x;
		cout<<x<<' '<<min(x,1000*1ll)*a+max((x-1000)*b,0ll)<<endl;
	}
	return 0;
}

B 可以发现字母c的坐标就是 ((c-‘a’)/9,(c-‘a’)%9)然后判断字符串的关系就好了

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=100010;
#define IOS ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
int n;
string a,b;
bool check(char a,char b)//相等或相邻返回1,其他返回0
{
	int x1=(a-'a')/9,y1=(a-'a')%9;
	int x2=(b-'a')/9,y2=(b-'a')%9;
	if(abs(x1-x2)<=1&&abs(y1-y2)<=1) return 1;
	return 0;
}

int main()
{
	cin>>n;
	while(n--)
	{
		cin>>a>>b;
		if(a==b) cout<<1<<endl;
		else if(a.size()==b.size())
		{
			bool flag=1;
			for(int i=0;i<a.size();i++)
				if(!check(a[i],b[i]))
				{
					flag=0;
					break;
				}
			if(flag) cout<<2<<endl;
			else cout<<3<<endl;
		}
		else cout<<3<<endl;
	}
	return 0;
}

C 播放顺序首位相连,播放完一首后自动跳到下一首,判断向前或向后按键的最小次数就可以了

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=100010;
#define IOS ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
ll n,t,s,a[N];
int main()
{
	cin>>t;
	while(t--)
	{
		cin>>s>>n;
		ll ans=0;
		for(int i=1;i<=n;i++) cin>>a[i];
		for(int i=1;i<n;i++)
		{
			a[i]=(a[i])%s+1;//播放完之后自动跳到下一首
			if(a[i]<=a[i+1]) ans+=min(a[i+1]-a[i],a[i]+s-a[i+1]);//分别是向前向后
			else ans+=min(a[i]-a[i+1],a[i+1]+s-a[i]);//分别是向后向前
		}
		cout<<ans<<endl;
	}
	return 0;
}

D 行首位置左移之后到上一行行末,行末位置右移之后到下一行行首,才发现这俩是逆过程,上移和下移都是如果目标行的字符数量比当前位置的列坐标小,移动之后直接到目标行的行末,否则列坐标不变。令行末位置的列坐标为0,其他点就不用变,直接记忆化搜索就行,每次分四种情况,上移或下移一位,左移直到上一行的行末,右移直到下一行的行首。
如果目标点在起点下方,可能存在先移到目标点下一行再左移的最短路径,反之亦然。

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=1010;
#define IOS ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
int n,t,w;
int s[N];
int b,c,d,e;
int ans;
int a[N][N];
void dfs(int x,int y,int num)
{
	if(a[x][y]<=num) return ;
	else a[x][y]=num;
	if(x==d)
	{
	 	ans=min(ans,abs(y-e)+num);//到达目标行,移到目标点
	 	//return ; 不能return
	}
	if(x>1)
	{
		dfs(x-1,s[x-1],num+y+1);//左移
		if(s[x-1]>=y) dfs(x-1,y,num+1);//上移
		else dfs(x-1,s[x-1],num+1);
	}
	if(x<n)
	{
		dfs(x+1,0,num+s[x]-y+1);//右移
		if(s[x+1]>=y) dfs(x+1,y,num+1);//下移
		else dfs(x+1,s[x+1],num+1);
	}
	return ;
}

int main()
{
	cin>>t;
	 
	while(t--)
	{
		memset(a,0x3f,sizeof a);
		cin>>n;
		ans=0x3f3f3f3f;
		for(int i=1;i<=n;i++) cin>>s[i];
		cin>>b>>c>>d>>e;
		dfs(b,c,0);
		cout<<ans<<endl;
	}
	return 0;
}

E 分别算位于哪个区域,再算分就可。

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=100010;
const double pi=3.1415926,eps=1e-6;
#define IOS ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
int n,t,b,d,s,w;


int main()
{
	cin>>t;
	 
	while(t--)
	{
		cin>>w>>b>>d>>s>>n;
		ll ans=0;
		double num=pi*2/w;
		for(int i=0;i<n;i++)
		{
			double x,y;
			cin>>x>>y;
			if(x*x+y*y<=b*b) ans+=50;
			else if(x*x+y*y<=s*s)
			{
				int res;
				double r=x*x+y*y;
				double e=asin(y/sqrt(r));//别忘开根号
				if(x<0&&y>0) e=pi-e;
				else if(x>0&&y<0) e=2*pi+e;
				else if(x<0&&y<0) e=pi+fabs(e);
				res=floor(e/num)+1;
				if(r<=d*d) res*=2;
				ans+=res;
			}
		}
		cout<<ans<<endl;
	}
	return 0;
}

F 已知n个点之间的交通方式和费用,在每个城市之间更换交通方式会有一个附加费用,求两点之间的最小费用,如果没有交通方式就是最短路的板子了,多了一个交通方式就多开一维呗,dist[i][j]就表示起点出发以第j种交通方式到达i点的最小费用,迪杰斯特拉外层循环应该也得多4倍(4种交通方式),地名预处理就可以了,具体看代码。

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=100010;
#define IOS ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
int t,n,s[N],f[N],h[N],e[N],ne[N],w[N],idx;
void add(int a,int b,int c,int d)
{
	s[idx]=d;
	e[idx]=b;
	w[idx]=c;
	ne[idx]=h[a];
	h[a]=idx++;
}
map<string,int> mp1;
int dist[N][4];
bool st[N][4];
int dij(int x,int y)
{
	memset(st,0,sizeof st);
	for(int i=0;i<4;i++) dist[x][i]=0;
	for(int i=0;i<4*n;i++)
	{
		int t=-1,d;
		for(int j=1;j<=n;j++)//找最短的地点和交通方式,t是地点,d是交通方式
			for(int k=0;k<4;k++)
				if(!st[j][k]&&((t==-1)||dist[j][k]<dist[t][d]))
					t=j,d=k;
		for(int j=h[t];j!=-1;j=ne[j])
		{
			int v=e[j];
			if(s[j]!=d) dist[v][s[j]]=min(dist[t][d]+w[j]+f[t],dist[v][s[j]]);//换交通方式了,多加一个换乘费用
			else dist[v][s[j]]=min(dist[t][d]+w[j],dist[v][s[j]]);//不用换
		}
		st[t][d]=1;
	}
	int ans=0x3f3f3f3f;
	for(int i=0;i<4;i++)//选最短的交通方式
		ans=min(ans,dist[y][i]);
	return ans;
} 
int main()
{
	cin>>t;
	mp1["AIR"]=0;//交通方式
	mp1["AIR"]=1;
	mp1["RAIL"]=2;
	mp1["TRUCK"]=3;
	while(t--)
	{
		idx=0;
		memset(h,-1,sizeof h);
		memset(dist,0x3f,sizeof dist);
		cin>>n;
		map<string,int> mp;
		for(int i=1;i<=n;i++) 
		{
			string str;
			cin>>str>>f[i];
			mp[str]=i;//给每个地名一个编号
		}
		int m,x;
		string a,b,c;
		cin>>m;
		for(int i=0;i<m;i++)
		{
			cin>>a>>b>>c>>x;
			add(mp[a],mp[b],x,mp1[c]);//每条边把交通方式也存进去
			add(mp[b],mp[a],x,mp1[c]);
		}
		cin>>a>>b;
		cout<<dij(mp[a],mp[b])<<endl;
	}
	return 0;
}

其他以后再补,溜了溜了

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值