1,acwing 920 最优乘车;2,acwing 903.昂贵的聘礼;3,cf Restricted RPS
1,最优乘车;
思路:
同条线路的所有站点之间的距离为1,所以给每条线路的站点之间互连距离为1的路径,求1好点到s的最短距离,再减去1即是最少换乘次数;
这道题有个注意的地方是它每行给出的线路车站数是不确定的,所以采用行读取,用到了stringstream;简单写下用法:
行的输入用getline,(如果在你要读入的数据之前还有输入,那就要吃个回车,用了快读不能用getchar,用cin.get();),
将行的数据放到stringstream里有两种写法:
一种是stringstream ssin(line);
一种是 stringstream ssin;ssin<<line;
将stringstream的数据取出来的方法:ssin>>();
注意区分和cin>> ; cout<< 的方向的区别;
#pragma GCC optimize(2)
#include<bits/stdc++.h>
#define rep1(i,a,n) for( int i=a;i<n;++i)
#define rep2(i,a,n) for( int i=a;i<=n;++i)
#define per1(i,n,a) for( int i=n;i>a;i--)
#define per2(i,n,a) for( int i=n;i>=a;i--)
#define quick_cin() cin.tie(0),cout.tie(0),ios::sync_with_stdio(false)
#define memset(a,i,b) memset((a),(i),sizeof (b))
#define memcpy(a,i,b) memcpy((a),(i),sizeof (b))
#define pro_q priority_queue
#define pb push_back
#define pf push_front
#define endl "\n"
#define lowbit(m) ((-m)&(m))
#define YES cout<<"YES\n"
#define NO cout<<"NO\n"
#define Yes cout<<"Yes\n"
#define No cout<<"No\n"
#define yes cout<<"yes\n"
#define no cout<<"no\n"
#define yi first
#define er second
using namespace std;
typedef pair<long long,long long>PLL;
typedef pair<int,int> PII;
typedef pair<int,PII> PIII;
typedef long long LL;
typedef double dob;
const int N = 510;
int m,n;
int g[N][N];
int dist[N];
int stop[N];
void bfs()
{
queue<int>q;
memset(dist,0x3f,dist);
q.push(1);
dist[1]=0;
while(q.size())
{
int t=q.front();q.pop();
rep2(i,1,n)
{
if(g[t][i]&&dist[i]>dist[t]+1)
{
dist[i]=dist[t]+1;
q.push(i);
}
}
}
}
signed main()
{
quick_cin();
cin>>m>>n;
string line;
cin.get();
while(m--)
{
getline(cin,line);
stringstream ssin(line);
int cnt=0,p;
while(ssin>>p)stop[cnt++]=p;
rep1(j,0,cnt)
rep1(k,j+1,cnt)
g[stop[j]][stop[k]]=1;
}
bfs();
if(dist[n]==0x3f3f3f3f)NO;
else cout<<max(dist[n]-1,0);
return 0;
}
2,昂贵的聘礼;
题目有些长,需要耐心分析题目;
首先看不考虑等级制度的建图方式,在得到每个物品的路径上,都有一条原价直接买到的,不妨设个虚拟源点S,都由S连该路径;
拿样例来看:
我们可以从该图中得到最短的路径,几所需的金币总数,花50买4物品,在拿200 换3物品,在加5000即可得到1;
那有了等级制度后,我们只可以在等级区间内进行交易,一共100等级,可以遍历整个等级区间,来得到最优解;
code
#pragma GCC optimize(2)
#include<bits/stdc++.h>
#define rep1(i,a,n) for( int i=a;i<n;++i)
#define rep2(i,a,n) for( int i=a;i<=n;++i)
#define per1(i,n,a) for( int i=n;i>a;i--)
#define per2(i,n,a) for( int i=n;i>=a;i--)
#define quick_cin() cin.tie(0),cout.tie(0),ios::sync_with_stdio(false)
#define memset(a,i,b) memset((a),(i),sizeof (b))
#define memcpy(a,i,b) memcpy((a),(i),sizeof (b))
#define pro_q priority_queue
#define pb push_back
#define pf push_front
#define endl "\n"
#define lowbit(m) ((-m)&(m))
#define YES cout<<"YES\n"
#define NO cout<<"NO\n"
#define Yes cout<<"Yes\n"
#define No cout<<"No\n"
#define yes cout<<"yes\n"
#define no cout<<"no\n"
#define yi first
#define er second
using namespace std;
typedef pair<long long,long long>PLL;
typedef pair<int,int> PII;
typedef pair<int,PII> PIII;
typedef long long LL;
typedef double dob;
const int N=110,INF=0x3f3f3f3f;
int n,m;
int w[N][N],level[N];
int dist[N];
int st[N];
int dijkstra(int down,int up)
{
memset(dist,0x3f,dist);
memset(st,0,st);
dist[0]=0;
rep2(i,1,n+1)
{
int t=-1;
rep2(j,0,n)
if(!st[j]&&(t==-1||dist[t]>dist[j]))
t=j;
st[t]=1;
rep2(j,1,n)
if(level[j]>=down&&level[j]<=up)
dist[j]=min(dist[j],dist[t]+w[t][j]);
}
return dist[1];
}
signed main()
{
quick_cin();
cin>>m>>n;
memset(w,0x3f,w);
rep2(i,1,n)w[i][i]=0;
rep2(i,1,n)
{
int price,cnt;
cin>>price>>level[i]>>cnt;
w[0][i]=min(price,w[0][i]);
while (cnt--)
{
int id,cost;
cin>>id>>cost;
w[id][i]=min(w[id][i],cost);
}
}
int res=INF;
rep2(i,level[1]-m,level[1])
res=min(res,dijkstra(i,i+m));
cout<<res;
return 0;
}
3,cf Restricted RPS
题意:a和b在玩石头剪刀布游戏,有n次回合,a赢的条件是至少n/2上取整次赢;
现给出a的石头次数,剪刀次数,布次数;和b的出手序列RPPS....(R是石头,P是布,S是剪刀)
如果a能赢,输出yes和使a能赢的出手序列(任意,但是长度和b相同);否则no;
思路:统计b的R,P,S的次数,a赢得对局的次数是min(P,R),min(S,P),min(R,S)的和;符合条件就赢,对应位置给它安排赢的出手,最后遍历没有安排到的位置给它安排出手;
#pragma GCC optimize(2)
#include<bits/stdc++.h>
#define rep1(i,a,n) for( int i=a;i<n;++i)
#define rep2(i,a,n) for( int i=a;i<=n;++i)
#define per1(i,n,a) for( int i=n;i>a;i--)
#define per2(i,n,a) for( int i=n;i>=a;i--)
#define quick_cin() cin.tie(0),cout.tie(0),ios::sync_with_stdio(false)
#define memset(a,i,b) memset((a),(i),sizeof (b))
#define memcpy(a,i,b) memcpy((a),(i),sizeof (b))
#define pro_q priority_queue
#define pb push_back
#define pf push_front
#define endl "\n"
#define lowbit(m) ((-m)&(m))
#define YES cout<<"YES\n"
#define NO cout<<"NO\n"
#define Yes cout<<"Yes\n"
#define No cout<<"No\n"
#define yes cout<<"yes\n"
#define no cout<<"no\n"
#define yi first
#define er second
using namespace std;
typedef pair<long long,long long>PLL;
typedef pair<int,int> PII;
typedef pair<int,PII> PIII;
typedef long long LL;
typedef double dob;
unordered_map<char,int>acs;
unordered_map<char,int>bcs;
char trans(char c)
{
if(c=='R')return 'P';
else if(c=='P')return 'S';
else return 'R';
}
char ans[1010];
void solve()
{
acs.clear();
bcs.clear();
memset(ans,0,ans);
int n;
cin>>n;
int mid=n+1>>1;
int a,b,c;
cin>>a>>b>>c;
acs['R']=a;
acs['P']=b;
acs['S']=c;
string s;
cin>>s;
int siz=s.size();
rep1(i,0,siz)bcs[s[i]]++;
int wins=0;
wins+=min(a,bcs['S']);
wins+=min(b,bcs['R']);
wins+=min(c,bcs['P']);
if(wins>=mid)
{
YES;
rep1(i,0,siz)
{
if(acs[trans(s[i])])
{
ans[i]=trans(s[i]);
acs[trans(s[i])]--;
}
}
rep1(i,0,siz)
{
if(!ans[i])
{
if(acs['R'])ans[i]='R',acs['R']--;
else if(acs['P'])ans[i]='P',acs['P']--;
else ans[i]='S',acs['S']--;
}
}
rep1(i,0,siz)cout<<ans[i];
cout<<endl;
}
else NO;
}
signed main()
{
quick_cin();
int T;
cin>>T;
while(T--)solve();
return 0;
}