Gym - 101341
B - Pursuing the Happiness
题意
给定一串字符串,问能否交换两个位置的字符使这个字符串中找不到"happiness"
思路
stirng.find查找"happiness"位置,若有返回位置pos,反之返回-1
有三种情况:
- 1.原串中开始时不存在"happiness",从头到尾遍历,交换相邻两个位置的字符串,看交换后的字符串是否存在"happiness",输出位置,结束程序
- 2.原串中存在1个"happiness",交换pos+1和pos+2位置处的字符,看是否存在"happiness"
- 3.原串中存在多个"happiness",查找第二个"happiness"所在位置为ppos,交换pos+1与ppos+2处字符串,看是否存在"happiness"
注意:输出位置要+1(Positions in the string are numbered from one.)
答案
#include <iostream>
#include<bits/stdc++.h>
#define ll long long
#define INF 0x3f3f3f3f
#define eps 1e-4
const int N = 2e5 + 10;
const int M = 111;
using namespace std;
string s;
string str;
int main()
{
cin>>s;
str.assign("happiness");
// int cnt=0;
if((int)s.find(str)==-1){
for(int i=0;i<(int)s.size();i++){
swap(s[i],s[i+1]);
if((int)s.find(str)==-1){
cout<<"YES"<<endl;
cout<<i+1<<" "<<i+2<<endl;
return 0;
}
swap(s[i],s[i+1]);
}
}
else{
int pos=(int)s.find(str);
int ppos=(int)s.find(str,pos+1);
if(ppos!=-1){
swap(s[pos+1],s[ppos+2]);
if((int)s.find(str)==-1){
cout<<"YES"<<endl;
cout<<pos+2<<" "<<ppos+3<<endl;
return 0;
}
}
else{
swap(s[pos],s[pos+1]);
if((int)s.find(str)==-1){
cout<<"YES"<<endl;
cout<<pos+1<<" "<<pos+2<<endl;
return 0;
}
}
}
cout<<"NO"<<endl;
// cout<<(int)s.find(str)<<endl;
return 0;
}
C - Urn with Balls
题意
有a个红球,b个绿球,c个未知颜色的球,最多取n个红球,m个绿球,问在符合条件的情况下最多取多少个球
思路
在判断过程中我们可以将c个球完全变为红球或者绿球来比较,sum=a+b+c为球的总数,如果a+c个红球大于n,则sum=min(sum,n);如果b+c个红球大于m,则sum=min(sum,m),sum即为所求数量
答案
#include <iostream>
#include<bits/stdc++.h>
#define ll long long
#define INF 0x3f3f3f3f
#define eps 1e-4
const int N = 2e5 + 10;
const int M = 111;
using namespace std;
int main()
{
ll a,b,c;
cin>>a>>b>>c;
ll n,m;
cin>>n>>m;
ll sum=a+b+c;
if(n<a+c) sum=min(sum,n);
if(m<b+c) sum=min(sum,m);
cout<<sum<<endl;
return 0;
}
D - Jumps
题意
在数轴上,给定n个可移动的距离,问通过这些可移动距离的无限次组合能否到达给定的x
思路
求这n个距离的gcd,所求gcd即为可以移动的最小的单位长度,若x能整除gcd则可到达,反之,无法到达。
答案
#include <iostream>
#include<bits/stdc++.h>
#define ll long long
#define INF 0x3f3f3f3f
#define eps 1e-4
const int N = 2e5 + 10;
const int M = 111;
using namespace std;
ll a[N];
int main()
{
ll n,x;
cin>>n>>x;
for(ll i=1;i<=n;i++){
cin>>a[i];
}
ll gcd=a[1];
for(ll i=2;i<=n;i++){
gcd=__gcd(gcd,a[i]);
}
x=abs(x);
if(x%gcd==0) cout<<"YES"<<endl;
else cout<<"NO"<<endl;
return 0;
}
E - Bonuses and Teleports
题意
给出 N 个跳点和 M 个目标点,跳点之间可任意传送,问从第一跳点开始,走遍所有目标点并返回第一跳点的最小 cost 是多少?
思路
见代码
答案
#include <iostream>
#include<bits/stdc++.h>
#define ll long long
#define INF 0x7fffffff
#define PI acos(-1)
#define eps 1e-7
const int mod = 1e9 + 7;
const int N = 2e5 + 10;
const int M = 111;
using namespace std;
ll a[N];
ll b[N];
ll c[N];
ll d[N];
int main()
{
int n,m;
cin>>n>>m;
a[0]=-INF;
a[n+1]=INF;
for(int i=1;i<=n;i++) cin>>a[i];
for(int i=1;i<=m;i++) cin>>b[i];
b[0]=b[m+1]=a[1];
for(int i=1,j=0;i<=m;i++){
while(a[j+1]<=b[i]) j++;
if(j>0) c[i]=b[i]-a[j];
else c[i]=INF;
if(j<n) d[i]=a[j+1]-b[i];
else d[i]=INF;
c[i]=min(c[i],d[i]);
}
ll ans=0;
c[0]=c[m+1]=0;
for(int i=1;i<=m+1;i++){
ll t=abs(b[i-1]-b[i]);
t=min(t,c[i-1]+c[i]);
ans+=t;
}
cout<<ans<<endl;
return 0;
}
G - I love Codeforces
题意
给你n个字符串,以及m个喜欢关系,如果u喜欢v,这时候u会把它的用户名改为 I_love_ 加上v当时的用户名
思路
模拟题,纯模拟会出MLE,RE,TLE等锅,只需要记录每个点喜欢(I_love_)的个数,以及每个点对应的最后一个点。
答案
法一:
#include <iostream>
#include<bits/stdc++.h>
#define ll long long
#define INF 0x3f3f3f3f
#define eps 1e-4
const int N = 2e5 + 10;
const int M = 111;
using namespace std;
string s[N];
vector<pair<int,int> > vp;
int main()
{
int n;
cin>>n;
for(int i=0;i<n;i++){
cin>>s[i];
}
//pair<int,int> pp;
int m;
cin>>m;
int u,v;
for(int i=0;i<m;i++){
cin>>u>>v;
u--,v--;
// vp[i].first=u;
// vp[i].second=v;
vp.push_back({u,v});
}
int cnt=0;
int next=0;
for(int i=(int)vp.size()-1;i>=0;i--){
if(vp[i].first==next){
cnt++;
next=vp[i].second;
}
}
for(int i=0;i<cnt;i++){
cout<<"I_love_";
}
cout<<s[next]<<endl;
return 0;
}
法二
#include <iostream>
#include<bits/stdc++.h>
#define ll long long
#define INF 0x3f3f3f3f
#define eps 1e-4
const int N = 2e5 + 10;
const int M = 111;
using namespace std;
struct node{
string name;
int sum;
}dp[N];
int main()
{
int n;
cin>>n;
for(int i=1;i<=n;i++){
cin>>dp[i].name;
dp[i].sum=0;
}
int m;
cin>>m;
for(int i=0;i<m;i++){
int u,v;
cin>>u>>v;
dp[u].name.assign(dp[v].name);
dp[u].sum=dp[v].sum+1;
}
while(dp[1].sum--) cout<<"I_love_";
cout<<dp[1].name<<endl;
return 0;
}
H - Perfect Ban
题意
随意删除一行一列,使矩阵剩下元素中的最大值是所有删除情况的最小情况。
思路
(这是别人的描述,感觉他比我说的清楚:-) )
根据贪心的思想,我们所删除的行和列应该是尽可能的包含可能多的大数,我们首先确定矩阵最大元素所在的行和列,那这个最大值我们是一定要删除的,所以下一个要寻找的应该是分别除去最大值所在行 列的次大值(如果只单纯的除去最大值找次大值的话,会忽略一种情况,就是我们的次大值和最大值在同一行同一列的情况,这样的话,我们必然是要删除最大值的行或者列的,这个次大值就没有了意义,偷偷告诉大家,这种情况就是这个题的样例8哦,我可是wa了好多发呢,qwq),我们找到次大值之后, 我们肯定是要删除的是(最大值的行,次大值的列) 或者 (次大值的行,最大值的列) 这其中的一种情况的, 那我们怎么判断删除哪种呢, 我们就可以非常直接的暴力跑这两种情况中矩阵剩下的元素哪种情况的小
答案:
#include <iostream>
#include<bits/stdc++.h>
#define ll long long
#define INF 0x3f3f3f3f
#define eps 1e-4
const int N = 1e6 + 10;
const int M = 1111;
using namespace std;
struct node{
int x;
int y;
int data;
}dp[N];
int a[M][M];
bool cmp(node x,node y){
return x.data>y.data;
}
int main()
{
int n,m;
cin>>n>>m;
int cnt=n*m;
for(int i=0;i<cnt;i++){
cin>>dp[i].data;
dp[i].x=i/m;
dp[i].y=i%m;
a[i/m][i%m]=dp[i].data;
}
sort(dp,dp+cnt,cmp);
int pos=0;
int x1=dp[pos].x;
int y1=dp[pos++].y;
int x2=dp[pos].x;
int y2=dp[pos++].y;
int x3=dp[pos].x;
int y3=dp[pos++].y;
if(x2!=x1&&y2!=y1){
if(x3==x1||y3==y2) cout<<x1+1<<" "<<y2+1<<endl;
else if(x3==x2||y3==y1) cout<<x2+1<<" "<<y1+1<<endl;
else cout<<x1+1<<" "<<y2+1<<endl;
}
else if(x2==x1){
if(x3!=x1) cout<<x1+1<<" "<<y3+1<<endl;
else{
while(dp[pos].x==x3){
pos++;
}
cout<<x1+1<<" "<<dp[pos].y+1<<endl;
}
}
else{
if(y3!=y1) cout<<x3+1<<" "<<y1+1<<endl;
else{
while(dp[pos].y==y3){
pos++;
}
cout<<dp[pos].x+1<<" "<<y1+1<<endl;
}
}
return 0;
}
M - Last Man Standing
题意
给你n个人,然后给你一个非递减序列a1 a2 an 分别表示每个人击杀人数,要求满足游戏规则输出YES并且输出每个人击杀的玩家序号,否则输出No.
思路
贪心,靠后的人尽量杀更靠后的人。
即将数组从后往前扫,对于每一个人i,都被此时最靠后的杀人数不为0的人杀,并且杀人的人杀人数减1。
判断不成立的条件是杀人总数大于等于总人数。
答案
#include <iostream>
#include<bits/stdc++.h>
#define ll long long
#define INF 0x3f3f3f3f
#define eps 1e-4
const int N = 2e5 + 10;
const int M = 111;
using namespace std;
ll a[N];
int main()
{
ll n;
cin>>n;
ll sum=0;
for(ll i=1;i<=n;i++){
cin>>a[i];
sum+=a[i];
}
if(n==1){
if(!a[1]) puts("YES");
else puts("NO");
}
else{
if(sum>=n) puts("NO");
else{
puts("YES");
int pos;
for(int i=n;i>=1;i--){
if(a[i]){
pos=i;
break;
}
}
while(a[pos]&&n!=1){
if(!a[n]){
cout<<pos<<" "<<n<<endl;
a[pos]--;
if(!a[pos]) pos--;
if(!a[n]) n--;
}
}
}
}
return 0;
}