A. Love Triangle
题意:题意要看清楚啊!(现在觉得标题真的很重要)这是一个三角恋问题,一开始呆了2分钟,在想多角恋了。。有n个数,如a[1]=2;意思就是1号喜欢的是2号。 问你存不存在三角恋的情况 存在输出YES 否则输出NO。
思路:遍历n 如果 a[a[a[i]]]==i,那么就存在三角恋。复杂度O(n)。
#include<bits/stdc++.h>
using namespace std;
typedef double db;
typedef long long ll;
int a[5500];
int main ()
{
//yyy_3y
// freopen("1.in","r",stdin);
int n;scanf("%d",&n);
for(int i=1;i<=n;i++) scanf("%d",&a[i]);
bool flag=0;
for(int i=1;i<=n;i++){
if(a[a[a[i]]]==i){
flag=1;
break;
}
}
if(flag) printf("YES\n");
else printf("NO\n");
return 0;
}
B. Hamster Farm
题意:n只仓鼠,k种箱子,只能买一种箱子,但是可以买任意多的箱子,每个箱子必须装满仓鼠,否则不能运输。问你买哪一种箱子可以带走最多的仓鼠,同时输出需要的箱子个数。
思路:三种情况。第一种,如果x>n,说明一个箱子也不需要;第二种,如果x==n,那只需要1个箱子;第三种,如果x
#include<bits/stdc++.h>
using namespace std;
typedef double db;
typedef long long ll;
int main ()
{
//yyy_3y
// freopen("1.in","r",stdin);
ll n,k; cin>>n>>k;
ll left=1e18;
ll ans1=1,ans2=0;
for(ll i=1;i<=k;i++){
ll x; cin>>x;
if(x<n){
if(n%x<left){
ans1=i;
left=n%x;
ans2=n/x;
}
}
else if(x==n){
ans1=i;
ans2=1;
}
}
cout<<ans1<<" "<<ans2<<endl;
return 0;
}
C. Convenient For Everybody
题意:一个n代表这个星球一天有多少小时,第二行是有每个地区有多少人想参加比赛。第三行是愿意参加比赛的时间的起始和终止。期中这个比赛持续时间为一小时。问你在什么时候开始比赛,参加的人数最多。
思路:倍增a[N],求前缀和。如果参加人数比初始的多,那就直接更新,如果相等去min。
#include<bits/stdc++.h>
using namespace std;
typedef double db;
typedef long long ll;
ll a[200000+17];
ll sum[200000+17];
int n,s,f;
int cal(int x)
{
if(s>=x) return s-x+1;
return s+n-x+1;
}
int main ()
{
//yyy_3y
// freopen("1.in","r",stdin);
scanf("%d",&n);
for(int i=1;i<=n;i++){
scanf("%lld",&a[i]);
a[i+n]=a[i];
sum[i]=sum[i-1]+a[i];
}
scanf("%d%d",&s,&f);
int tmp=f-s;
int res=100000+1;
ll ans=sum[tmp];
ll mx=sum[tmp];
for(int i=1;i<=n;i++){
ans=ans-a[i]+a[tmp+i];
if(ans>mx) {
mx=ans;
res=cal(i+1);
}else if(ans==mx){
int tmp=cal(i+1);
res=min(tmp,res);
}
}
printf("%d\n",res);
return 0;
}
D. Love Rescue
题意:给长度为n的串a,b;每次可以花费1使字母x改变为任意一个字母y,x->y(y->x)都行,且无限次更换,问使两串相同的最少花费,并输出x,y。
思路:并查集。
#include<bits/stdc++.h>
using namespace std;
typedef double db;
typedef long long ll;
const int N=1e5+7;
char a[N],b[N];
int pre[30];
vector<pair<char,char> >stk;
int findx(int x)
{
return pre[x]==x?x:pre[x]=findx(pre[x]);
}
int main ()
{
//yyy_3y
// freopen("1.in","r",stdin);
int n;
scanf("%d%s%s",&n,a+1,b+1);
for(int i=0;i<26;i++) pre[i]=i;
for(int i=1;i<=n;i++){
int fx=findx(a[i]-'a');
int fy=findx(b[i]-'a');
if(fx!=fy){
pre[fx]=fy;
}
}
int tot=0;
for(int i=0;i<26;i++) if(pre[i]!=i) tot++;
printf("%d\n",tot);
for(int i=0;i<26;i++) if(pre[i]!=i) printf("%c %c\n",i+'a',pre[i]+'a');
}
E. Maximize!
题意:一个多重集合,刚开始为空,有两种操作:
1.加入一个数(保证加入的数大于等于集合中现有的数)
2.从multiset中选出一个子集,使得max-average最大,并输出。
思路:尺取法一波。
思路二:三分卡。(另开专题)
#include<bits/stdc++.h>
using namespace std;
typedef double db;
typedef long long ll;
int a[510000];
int cnt=0,maxx=0,pre=0;
double ans;
ll sum;
int main ()
{
//yyy_3y
// freopen("1.in","r",stdin);
int q;scanf("%d",&q);
while(q--){
int type;
scanf("%d",&type);
if(type==1){
scanf("%d",&a[++cnt]);
sum+=a[cnt]-maxx;
maxx=a[cnt];
while(pre<cnt&&maxx-1.0*sum/(pre+1)<maxx-1.0*(sum+a[pre+1])/(pre+2))
sum+=a[++pre];
if(maxx-1.0*sum/(pre+1)>ans) ans=maxx-1.0*sum/(pre+1);
}
else
printf("%.10f\n",ans);
}
return 0;
}