codefoce div2 A. Kids Seating B. Saving the City题解

A. Kids Seating
链接:http://codeforces.com/contest/1443/problem/A
题意:你是老师,有4n个座位,下标是1~4n,你需要安排n个小孩座哪里,有2个要求:
1.任意两个小孩座位号a,b。gcd(a,b)不能等于1;
2.任意两个小孩座位号a,b。a不能整除吧,b不能整除a。
输出n个小孩子的座位号分别是多少
思路:
只要最大的座位号小于最小的座位号的两倍就行
因为相邻的两个数字gcd等于1,所以我让每个数字间隔2即可
2x,其中x为可容纳小孩数量,第一个位子从2x开始每次加2输出

#include<iostream>
#include<unordered_set>
#include<cstdio>
#include<cstring>
#include<string>
#include<algorithm>
#include<cmath>
#include<math.h>
#include<vector>
#include<stack>
#include<queue>
#include<map>
#include<set>
#define ll long long
using namespace std;
int t,n;
int main() {
	ios::sync_with_stdio(false);
	cin.tie(0);
    //freopen("test.in","r",stdin);
    //freopen("test.out","w",stdout);
	cin>>t;
	while(t--)
	{
		cin>>n;
		for(int i=0;i<n;i++)
			cout<<n*2+i*2<<" ";
		cout<<endl;
	}
	return 0;
}

B. Saving the City
链接:http://codeforces.com/contest/1443/problem/B
题意:
给你一个字符串由0 1构成,你需要消除所有的1,如果消除一个1的附近有1(范围x-1,x+1)则一起被消灭否则什么都不会发生。现在你有2种操作:
1.消除一个1 你需要花费 a个硬币
2.将一个0 变成 1 你需要花费 b个硬币
求最少花费硬币数
思路:
分类讨论 如果a<=b 则直接输出1有多少联通块,因为你直接消除1的花费一定比添1后消除花费少!
如果 a>b 贪心如果距离最近的2个1中间0的个数为x,那么满足xb+a<=2a的时候,直接消除2个1的连通块花费的硬币一定比将中间0全部变为1并且只消除1次的花费多,所以记录xb+a<=2a,记录x,最后总花费=a的花费+b花费。

#include<iostream>
#include<unordered_set>
#include<cstdio>
#include<cstring>
#include<string>
#include<algorithm>
#include<cmath>
#include<math.h>
#include<vector>
#include<stack>
#include<queue>
#include<map>
#include<set>
#define ll long long
using namespace std;
const int N=1e4+10;
int num[N];
int t,a,b;
int main() {
	ios::sync_with_stdio(false);
	cin.tie(0);
    //freopen("test.in","r",stdin);
    //freopen("test.out","w",stdout);
	cin>>t;
	while(t--)
	{
		cin>>a>>b;
		string s;
		cin>>s;
		int num1=0,num2=0,flag=0;
		for(int i=0;i<s.size();i++)
		{
			if(s[i]=='1'&&!flag)
			{
				num1++;
				flag=1;
			}
			else if(s[i]=='1') continue;
			else flag=0;
		}
		flag=0;
		int sum=0,countnum=0,number=0;
		if(a<=b) cout<<num1*a<<endl;
		else 
		{
			for(int i=0;i<s.size();i++)
			{
				if(s[i]=='1') flag=1;
				if(flag&&s[i]=='0') num2++;
				else if(num2&&s[i]=='1')
				{
					num[++countnum]=num2;
					num2=0;
				}
			}
			sort(num+1,num+1+countnum);
			/*
			for(int i=1;i<=countnum;i++) cout<<num[i]<<" ";
			cout<<endl;
			cout<<num1<<endl;
			*/
			for(int i=1;i<=countnum;i++)
			{
				if(num[i]*b+a<=2*a)
				{
					sum+=num[i];
					number++;
				}
				else break;
			}
			cout<<sum*b+(num1-number-1)*a+a<<endl;
		}
	}
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值