Codeforces Round #364 (Div. 2)(A,B,C,D)

还是自己菜的原因,cf一直打不好,希望借写博客来记录并提示自己吧。。


A:有n辆车(n是偶数),n/2个人,每人分配两辆车,每辆车都有一个标志值(具体代表什么,我也忘了),现在要求给每个人分配的车的价值总和都一样,输出每个人的车子号码。

题解:暴力枚举;求出所有车子的总和sum,s=2*sum / n就是 每个人分配的车子价值总和,然后对每个没有被记录的 a[i] 找到 一个同样没有标记的 s-a[i] 的元素,输出,并将这两个元素标记,即可。

#include <bits/stdc++.h>
#define nloop(a,b,c) for(LL a=b;a>=c;a--)
#define loop(a,b,c) for(LL a=b;a<=c;a++)
#define clr(a,b) memset(a,b,sizeof a)
#define x first
#define y second
#define LL long long
//#define debug
#define maxn 1000005
using namespace std;
int a[5500],book[5000];
int ser(int x,int n)
{
    loop(i,1,n)
    if(a[i]==x&&book[i]>0)
        return i;
}
int main()
{
	//freopen("data.txt","r",stdin);
	int n,s=0,p,d;
	scanf("%d",&n);
	loop(i,1,n)
			scanf("%d",&a[i]),s+=a[i],book[i]=1;
	p=n/2;
	d=s/p;
	//cout<<d<<endl;
	loop(i,1,n)
	{
		if(book[i]>0)
		{
		    //cout<<book[d-a[i]]<<endl;
		    book[i]--;
		    int pos=ser(d-a[i],n);
		    book[pos]--;
		    cout<<i<<" "<<pos<<endl;
		}
	}

}

B:有个棋盘n*n那么大,有m个皇后,每次放一个皇后进去,然后统计当前还有多少个空格是可以走的

题解:n很大,不可能暴力去枚举或者开个二维数组去标记,我们用row[i]表示第i行是否能走,col[i]表示第i列是否能走,add1表示行被标记的个数,add2表示列被标记的个数,如果把x,y放到棋盘,初始ans=n*n,分了三种情况

1:x行,y列都没有被标记过 ,那么ans -=n-add1+n-add2-1,add1++,add2++;

2:x行标记过,y列没被标记,那么ans -=n-add1,add2++;

3:x行没被标记过,y列被标记过,那么ans-=n-add2,add1++;

#include <bits/stdc++.h>
#define nloop(a,b,c) for(LL a=b;a>=c;a--)
#define loop(a,b,c) for(LL a=b;a<=c;a++)
#define clr(a,b) memset(a,b,sizeof a)
#define x first
#define y second
#define LL long long
//#define debug
#define maxn 1000005
using namespace std;
int row[maxn],col[maxn];
int main()
{
	//freopen("data.txt","r",stdin);
	LL n,m,x,y,ans;
	scanf("%I64d %I64d",&n,&m);
	ans=n*n;
	LL add1=0,add2=0;
	loop(i,1,m)
	{
		scanf("%I64d %I64d",&x,&y);
		if(!row[x]&&!col[y])
        {
            ans-=2*(n-1)-add1-add2-1;
            add1++;
            add2++;
        }
        else if(!row[x])
        {
            ans-=n-add1;
            add2++;
        }
        else if(!col[y])
        {
            ans-=n-add2;
            add1++;
        }
		cout<<ans<<" "<<endl;
		row[x]=col[y]=1;
	}

}
C:对于一个字符串,每个字符串都是大写或小写字母,求最短的长度,完全包含该字符串里所有字符

题解:经典尺取法。先O(n)求出总共有多少种字符num。把字符一个一个加到队列,统计队列里面的字符种数,不够num,继续加入,如果够了,更新ans=min(ans,Q.size()),将第一个字符出队,重复上述操作。

#include <bits/stdc++.h>
#define nloop(a,b,c) for(LL a=b;a>=c;a--)
#define loop(a,b,c) for(LL a=b;a<=c;a++)
#define clr(a,b) memset(a,b,sizeof a)
#define x first
#define y second
#define LL long long
#define maxn 100005
using namespace std;
int flag[300];
int main()
{
	//freopen("data.txt","r",stdin);
	int num=0,n;
	queue<char> Q;
	string ch;
	cin>>n>>ch;
	loop(i,0,ch.size()-1)
	{
			if(!flag[ch[i]])
				num++,flag[ch[i]]=1;
	}
	clr(flag,0);
	int t=0,ans=n+1,l,r;
	loop(i,0,ch.size()-1)
	{
			if(t<num)
            {
                Q.push(ch[i]);
                if(!flag[ch[i]]) t++;
                flag[ch[i]]++;
            }
            if(t==num)
            {
                while(!Q.empty()&&flag[Q.front()]>1)
                    flag[Q.front()]--,Q.pop();
				ans=min(ans,(int)Q.size());
				flag[Q.front()]--;
				Q.pop();
				t--;
            }
	}
	cout<<ans<<endl;
}

D:有n个学生,一辆车,目的地距离为L ,学生速度为v1,车速度为v2,求最短的时间使得所有的学生都到达目的地。

题解:如果时间最小 那么最后一定是每个人都同时到达终点
可以假定 所有人 走路时间都为t1 搭车时间都为t2,那么车子每次回头去载人的时间就是t3=t2*(v2-v1)/(v2+v1)
可以列出
(num-1)*( t2 + t3 )*v1+t2*v2=L
 t2*v2+t1*v1=L
解出t1 t2 相加就是答案了

#include <bits/stdc++.h>
#define nloop(a,b,c) for(LL a=b;a>=c;a--)
#define loop(a,b,c) for(LL a=b;a<=c;a++)
#define clr(a,b) memset(a,b,sizeof a)
#define x first
#define y second
#define LL long long
#define maxn 100005
using namespace std;
int flag[300];
int main()
{
	//freopen("data.txt","r",stdin);
	int num=0,n,k;
	double l,v1,v2;
	cin>>n>>l>>v1>>v2>>k;
	double t,t1,t2;
	num=n/k+((n%k)?1:0);
	t2=1.0*l/(v2+1.0*v1*(num-1)*(2*v2/(v1+v2)));
	t=t2+(2*v2/(v1+v2))*(num-1)*t2;
	printf("%.10lf\n",t);
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值