不知不觉,已经快两个月没有写题了,一月份复习+数模,忙到除夕夜前才赶回家,今年大年初二,重拾一场cf来喜迎新年
不过这场比赛倒是有个小花絮,2h的比赛,体温一路上升,赛前还生龙活虎,等赛完直接飙升到39度,在家躺尸躺了一周多才退烧,不过也算给自己一个难得的休息机会了,本以为是个上分的好机会,年后才发现第四题被fst了,无奈赶紧研究一下吧
A. Love Triangle
思路:简单的判断三元环问题,枚举每个起点找一遍三元终点看是否为起点即可
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <vector>
#include <cstring>
#include <map>
#include <cmath>
#include <string>
#include <queue>
#include <stack>
using namespace std;
const int maxn = 5000+10;
int f[maxn];
int main()
{
int n;
while(scanf("%d",&n)!=EOF)
{
bool love = false;
for(int i=1;i<=n;i++)
{
scanf("%d",&f[i]);
}
if(n==2)
{
printf("NO\n");
continue;
}
for(int i=1;i<=n;i++)
{
if(f[f[f[i]]] == i)
{
love = true;
break;
}
}
if(love)
{
printf("YES\n");
}
else
{
printf("NO\n");
}
}
return 0;
}
B. Hamster Farm
思路:简单贪心问题,因为只有一种盒子,且必须放满,那么贪心求余值最小的即可,最后注意一下结果可能超int,加个long long,算个小坑吧
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <vector>
#include <cstring>
#include <map>
#include <cmath>
#include <string>
#include <queue>
#include <stack>
using namespace std;
const int maxn = 1e5+10;
/*
typedef struct HAMSTER
{
long long a;
int d;
}Hamster;
Hamster h[maxn];
bool cmp(const Hamster &h1,const Hamster &h2)
{
if(h1.a<=h2.a&&h1.d<=h2.d)
{
return true;
}
else
{
return false;
}
}
long long a[maxn];*/
int main()
{
long long n,k;
while(scanf("%I64d%I64d",&n,&k)!=EOF)
{
int mind = 0;
long long num;
long long lef = n + 1LL;
for(int i=1;i<=k;i++)
{
long long a;
scanf("%I64d",&a);
long long temp = n%a;
if(temp < lef)
{
lef = temp;
num = n/a;
mind = i;
}
}
printf("%d %I64d\n",mind,num);
/*long long mina = 1e18+10;
int mind = 0;
for(int i=0;i<k;i++)
{
scanf("%I64d",&h[i].a);
h[i].d = i+1;
if(h[i].a < mina)
{
mina = h[i].a;
mind = h[i].d;
}
}*/
/*for(int i=0;i<k;i++)
{
cout << h[i].a << "*" << h[i].d <<endl;
}
sort(h,h+k,cmp);*/
// printf("%d %d\n",mind,(int)(n/mina));
/*for(int i=0;i<k;i++)
{
cout << h[i].a << "*" << h[i].d <<endl;
}*/
}
return 0;
}
C. Convenient For Everybody
思路:选定开会时间,使得不同时区尽可能多的人能参与到会议当中
这题最优化问题,由于时间较少,当然是枚举每个时间点进行比较判断,模拟一下即可
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <vector>
#include <cstring>
#include <map>
#include <cmath>
#include <string>
#include <queue>
#include <stack>
using namespace std;
const int maxn = 3e5+10;
int a[maxn];
int main()
{
int n;
while(scanf("%d",&n)!=EOF)
{
//memset(d,0,sizeof(d));
int s,f;
for(int i=1;i<=n;i++)
{
scanf("%d",&a[i]);
}
scanf("%d%d",&s,&f);
int st = s;
int en = f-1;
int maxnum = 0;
int lastnum = 0;
int maxt = 1;
for(int t = st;t <=en;t++)
{
maxnum += a[t];
}
lastnum = maxnum;
for(int t = 2; t<=n; t++)
{
int tempnum = lastnum;
st--;
if(st == 0)
{
st = n;
}
tempnum = tempnum - a[en] + a[st];
en--;
if(en == 0)
{
en = n;
}
if(tempnum > maxnum)
{
maxnum = tempnum;
maxt = t;
}
lastnum = tempnum;
//cout << t << "#" << tempnum << endl;
}
printf("%d\n",maxt);
//cout << maxnum << "*" << endl;
}
return 0;
}
D. Love Rescue
思路:对于两个字符串,提供一种改字母方案,使得更改尽可能少的字母后两个字符串完全相同
原来的思路是枚举字母,若存在不同则更改,并用并查集记录
最后,由于好久都没写程序了,一定要注意,并查集千万不能用pre啊,用finds,否则压缩不完全,巨坑啊
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <vector>
#include <cstring>
#include <map>
#include <cmath>
#include <string>
#include <queue>
#include <stack>
using namespace std;
const int maxn = 1e5+10;
char pullover[maxn],shirt[maxn];
char re1[maxn],re2[maxn];
int pre[30];
int finds(int x)
{
int r = x;
while(pre[r]!=r)
{
r = pre[r];
}
int i=x ,j;
while(pre[i]!=r)
{
j = pre[i];
pre[i] = r;
i = j;
}
return r;
}
void join(int x,int y)
{
int fx = finds(x);
int fy = finds(y);
if(fx > fy)
{
int temp = fx;
fx = fy;
fy = temp;
}
if(fx!=fy)
{
pre[fy] = fx;
}
}
int main()
{
int n;
while(scanf("%d",&n)!=EOF)
{
int sum = 0;
for(int i=1;i<=26;i++)
{
pre[i] = i;
}
scanf("%s%s",pullover,shirt);
for(int s1=1;s1<=26;s1++)
{
for(int s2=1;s2<=26;s2++)
{
if(finds(s1)==finds(s2))
{
continue;
}
for(int i=0;i<n;i++)
{
if((finds(pullover[i]-'a'+1)==finds(s1)&&finds(shirt[i]-'a'+1)==finds(s2))||(finds(pullover[i]-'a'+1)==finds(s2)&&finds(shirt[i]-'a'+1)==finds(s1)))
{
re1[sum] = s1;
re2[sum] = s2;
sum++;
//cout << 'a' + s1 - 1 << 'a' + s2 - 1 << 'a' + finds(s1) - 1 << 'a' + finds(s2) - 1 << endl;
join(s1,s2);
break;
}
}
}
}
printf("%d\n",sum);
for(int i=0;i<sum;i++)
{
printf("%c %c\n",re1[i]+'a'-1,re2[i]+'a'-1);
}
}
return 0;
}