本文主要是介绍hope实验室预备役第4次测试题解,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
目录
1.Foreign Exchange
2.Takahashi Gets Lost
3.Sasha and the Beautiful Array
4.Sasha and the Drawing
5.Sasha and the Casino
6.Only one of two
7.村村通
8.传送门
1.Foreign Exchange
原题链接
Sample 1
Inputcopy | Outputcopy |
---|---|
4 5 7 0 3 2 2 4 3 5 2 | 5 |
Sample 2
Inputcopy | Outputcopy |
---|---|
10 32 6 46 9 37 8 33 14 31 5 5 5 3 1 4 3 2 2 3 2 3 2 4 4 3 3 3 1 | 45 |
这道题给出了有多少每国的货币,让我们求出最多可以拥有多少第n国的货币,又有第i国可以兑换第i+1国的货币的特性,我们直接将所有的第i国的货币换成i+1国的货币便可以求出第n国的货币。
下面是AC代码:
#include<bits/stdc++.h>
using namespace std;
long long n,a[200010];
int main()
{cin>>n;for(int i=1;i<=n;i++) cin>>a[i];for(int i=1;i<=n-1;i++){int in,out;cin>>in>>out;a[i+1]+=(a[i]/in)*out;//看看能换多少份}cout<<a[n]<<endl;return 0;
}
注意:需要long long类型,不然会爆int!
2.Takahashi Gets Lost
原题链接
Sample 1
Inputcopy | Outputcopy |
---|---|
6 7 5 LULDR ####### #...#.# ##...## #.#...# #...#.# ####### | 2 |
Sample 2
Inputcopy | Outputcopy |
---|---|
13 16 9 ULURDLURD ################ ##..##.#..####.# ###.#..#.....#.# #..##..#####.### #...#..#......## ###.##.#..#....# ##.#####....##.# ###.###.#.#.#..# ######.....##..# #...#.#.######.# ##..###..#..#.## #...#.#.#...#..# ################ | 6 |
按照给出的字符串(只含L,R,D,U),L为向左走一步,R为向右走一步,D为向下走一步,U为向上走一步。
我们可以遍历地图的每一个位置(这个位置本身要是陆地),看看执行字符串的操作会不会走到海洋,如果完成所以操作也没有走到海洋,那么此位置为一个可能落地位置,答案计数加1。
下面是AC代码:
#include<bits/stdc++.h>
using namespace std;
int n,m,k,ans;
string mp[600],t;
int dx[4]={1,-1,0,0},dy[4]={0,0,1,-1};//下,上,右,左
bool check(int x,int y)
{if(mp[x][y]=='#') return false;for(int i=0;i<k;i++){if(t[i]=='D')x+=dx[0],y+=dy[0];else if(t[i]=='U')x+=dx[1],y+=dy[1];else if(t[i]=='R')x+=dx[2],y+=dy[2];else x+=dx[3],y+=dy[3];if(mp[x][y]=='#')//若发现当前位置不合理,直接返回错误 return false;}return true;//这个位置可以完成操作
}
int main()
{cin>>n>>m>>k>>t;for(int i=0;i<n;i++) cin>>mp[i];for(int i=1;i<n-1;i++){//因为四周固定都是海洋,所以从1到n-2(m-2)就行 for(int j=1;j<m-1;j++){if(check(i,j))ans++;}}cout<<ans<<endl;return 0;
}
3.Sasha and the Beautiful Array
原题链接
Sample 1
Inputcopy | Outputcopy |
---|---|
5 3 2 1 3 3 69 69 69 5 100 54 80 43 90 4 3 4 3 3 2 2 1 | 2 0 57 1 1 |
这道题没什么好讲的,直接排序,累加后一个元素减去前一个元素就是最大美丽度。
下面是AC代码:
#include<bits/stdc++.h>
using namespace std;
long long n,a[200];
int main()
{int t;cin>>t;while(t--){cin>>n;for(int i=1;i<=n;i++){cin>>a[i];}sort(a+1,a+1+n);long long ans=0;for(int i=2;i<=n;i++){ans+=(a[i]-a[i-1]);}cout<<ans<<endl;}return 0;
}
4.Sasha and the Drawing
原题链接
Sample 1
Inputcopy | Outputcopy |
---|---|
7 3 4 3 3 3 10 3 9 4 7 7 11 2 3 | 2 2 6 5 4 6 2 |
纯思路题,当然我也搞不懂原理,但是我根据图片和输入样例发现,一个着色单元格最多可以包含两条对角线,当对角线满时(也就是对角线的数量为4n-2),只需要将方形矩阵的上下两条边的单元格全部着色即可,也就是n*2个单元格。
根据上面和分析样例,于是出现了下面AC代码:
#include<bits/stdc++.h>
using namespace std;
int main()
{int t;cin>>t;while(t--){long long n,k;cin>>n>>k;if(k==4*n-2)cout<<n*2<<endl;else{long long ans=(k+1)/2;cout<<ans<<endl;}}return 0;
}
5.Sasha and the Casino
原题链接
Sample 1
Inputcopy | Outputcopy |
---|---|
9 2 1 7 2 1 1 2 3 15 3 3 6 4 4 5 5 4 7 4 88 1000000000 25 69 231 13 97 18806 | YES NO YES NO NO YES NO NO NO |
既然需要保证他能在某个时刻拥有任意个硬币,那么就要考虑连续输到下一次不会输的情况。
下面是AC代码:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
int main()
{ll t;cin>>t;while(t--){ll k,x,a;cin>>k>>x>>a;ll f1,f2,flag=0;f1=1;for(int i=0;i<x-1;i++){f2=(f1)/(k-1)+1;f1+=f2;if(f1>a)//要是一直输,钱不够输 {flag=1;break;} }if(flag||(a-f1)*k<=a) cout<<"NO"<<endl;//输完,保底的本钱比原来还少也不能某个时刻达到任意钱 else cout<<"YES"<<endl;}return 0;
}
6.Only one of two
原题链接
Sample 1
Inputcopy | Outputcopy |
---|---|
2 3 5 | 9 |
Sample 2
Inputcopy | Outputcopy |
---|---|
1 2 3 | 5 |
Sample 3
Inputcopy | Outputcopy |
---|---|
100000000 99999999 10000000000 | 500000002500000000 |
题目要求我们找出只能被n和m其中一个整除的第k个数。
第一个样例很好解释题目的要求,是不是想暴力求解,但是看这数据范围,估计算到开学也算不完。
所以我们可以想到使用二分去解决它,首先把left~right的范围定义得大一些,我们需要的答案就在这个范围里面,记得里面的数据都需要用long long类型哦!
下面是AC代码:
#include<bits/stdc++.h>
using namespace std;
long long n,m,k,l=1,r=2e18;
int gc(long long a,long long b) //找最大公约数
{ if(b) while((a%=b) && (b%=a)); return a+b;
}
int main()
{cin>>n>>m>>k;long long f=n*m/gc(n,m);//最大公倍数,用于减去这个数可以同时被n和m整除的情况 while(l<r){long long mid=(l+r)/2;if(mid/n+mid/m-mid/f*2>=k)//mid/n代表有多少个数被n整除,mid/f*2为有多少数同时被n和m整除, r=mid;// 如果mid/n+mid/m-mid/f*2大于我们要找的第k个数,什么当前的mid大于我们要找的答案,压缩边界 else l=mid+1;}cout<<l<<endl;return 0;
}
7.村村通
原题链接
Sample 1
Inputcopy | Outputcopy |
---|---|
4 2 1 3 4 3 3 3 1 2 1 3 2 3 5 2 1 2 3 5 999 0 0 | 1 0 2 998 |
一个最小生成树的模板题,直接将有的边先建入,再看看还需要建多少边才能串通全部村子。
下面是AC代码:
#include<bits/stdc++.h>
using namespace std;
int n,m,pre[1001];
int find(int x)
{if(pre[x]==x) return x;return pre[x]=find(pre[x]);
}int main()
{while(scanf("%d",&n)){if(n!=0) cin>>m;//输入停止标志 else break;int ans=0;for(int i=1;i<=n;i++) pre[i]=i;while(m--){int a,b;cin>>a>>b;pre[find(a)]=find(b);}for(int i=1;i<=n;i++){for(int j=i+1;j<=n;j++){if(find(i)!=find(j)){ans++;//建入一个边,答案+1 pre[find(i)]=find(j);}}}cout<<ans<<endl;}return 0;
}
8.传送门
原题链接
Sample 1
Inputcopy | Outputcopy |
---|---|
4 5 1 2 3 1 3 6 2 3 4 2 4 7 3 4 2 | 14 |
对于这道题我一直在想,传送门应该要怎么建立,后面才看到这数范围(n<=100),所以是需要对任意两个教学楼都建立一次传送门,看哪个的最短路径和最小。
那就使用全源最短路径Floyd 算法来暴力求解,但是我们试想一下,这样就有5层for循环,还是会超时,所以我们需要缩减到4层。
因为只有使用了传送门才会影响最短路径,所有有了下面代码。
for(int x=1;x<=n;x++){for(int y=1;y<=n;y++){if(mp2[x][j]<inf&&mp2[j][y]<inf)mp2[x][y]=min(mp2[x][y],mp2[x][j]+mp2[j][y]);}}for(int x=1;x<=n;x++){for(int y=1;y<=n;y++){if(mp2[x][i]<inf&&mp2[i][y]<inf)mp2[x][y]=min(mp2[x][y],mp2[x][i]+mp2[i][y]);}}
i,j是建传送门的教学楼,会影响最短路径,所以只需要分别对这两个教学楼的最短路径的计算更新即可。
下面是AC代码:
#include<bits/stdc++.h>
#define inf 1234567890
using namespace std;
int n,m,mp1[120][120],mp2[120][120],ans=inf;
void back()//返回原图
{for(int i=1;i<=n;i++){for(int j=1;j<=n;j++){mp2[i][j]=mp1[i][j];}}
}
int main()
{cin>>n>>m;for(int i=1;i<=n;i++)for(int j=1;j<=n;j++)mp1[i][j]=inf;for(int i=1;i<=m;i++){int x,y,z;cin>>x>>y>>z;mp1[x][y]=mp1[y][x]=z;}for(int k=1;k<=n;k++){for(int i=1;i<=n;i++){for(int j=1;j<=n;j++){if(mp1[i][k]<inf&&mp1[k][j]<inf)//先计算没有建立传送门的最短路径 mp1[i][j]=min(mp1[i][j],mp1[i][k]+mp1[k][j]);}}}for(int i=1;i<=n;i++){for(int j=1;j<=n;j++){back();//每次返回原图 mp2[i][j]=mp2[j][i]=0;//建立传送门 for(int x=1;x<=n;x++){for(int y=1;y<=n;y++){if(mp2[x][j]<inf&&mp2[j][y]<inf)mp2[x][y]=min(mp2[x][y],mp2[x][j]+mp2[j][y]);}}for(int x=1;x<=n;x++){for(int y=1;y<=n;y++){if(mp2[x][i]<inf&&mp2[i][y]<inf)mp2[x][y]=min(mp2[x][y],mp2[x][i]+mp2[i][y]);}}int cnt=0;for(int x=1;x<=n;x++){for(int y=x+1;y<=n;y++){cnt+=mp2[x][y];//计算最短路径和 }}ans=min(ans,cnt);//更新最小 }}cout<<ans<<endl;return 0;
}
这篇关于hope实验室预备役第4次测试题解的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!