Codeforces Round #407 (Div. 2) ABCD

A:

                                                                        Anastasia and pebbles

题意:

       有两个口袋,每个口袋的能装k个鹅卵石, 且只能装同一种鹅卵石,给定不同类型的鹅卵石的个数,每一天用这两个口袋去装鹅卵石, 问:最少几天能将所有的鹅卵石带走

求解: 
        求出不同种类的所有的鹅卵石总共需要几个口袋, 然后总口袋数/2即可(注意,口袋可以不用装满,但必须是同一个类型的鹅卵石)

Code:
#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
#include<string>
#include<queue>
#include<stack>
using namespace std;
const int maxn = 100005;
int num[maxn];
bool cmp(int a, int b){
	return a>b;
}
int main()
{
	int n, k=0;
	int sum=0;
	scanf("%d %d", &n, &k);
	for(int i=1; i<=n; i++){
		scanf("%d", &num[i]);
		sum += num[i]/k;
		if(num[i] - (num[i]/k*k)>0) sum++;
	}
	printf("%d\n", (sum+1)/2);
	return 0;
}

B.
                                                                Masha and geometric depression
题意:
         给出一个等比数列的b1和q,  则 bn=bn-1 * q;  求在 |bn|<=L以及bn不能出现在给出的Bad数组中的条件下, 共有多少个数bn,  可以重复, 且允许b=q=0;若无穷个,则输出inf,否则输出个数
求解: 
        对b=0,q=0, q=+1,q=-1进行特判, 因为这几种情况可能产生inf, 其他情况不会。对于其他情况,直接求出从b1到
|bn|<=L总共有几个数, 其中满足条件但是在Bad数组中出现的不计算在内。

Code:
#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
#include<string>
#include<queue>
#include<stack>
#include<cmath>
using namespace std;
const int maxn = 100005;
int num[maxn];
__int64 b, q, l, m;
int main()
{
	scanf("%I64d %I64d %I64d %I64d", &b, &q, &l, &m);
	int i;
	for(i=1; i<=m; i++){
		scanf("%d", &num[i]);
	}
	sort(num+1, num+1+m);
	if(abs(b) > l) 		 printf("0\n");
	else if(q==1||q==-1 || q==0 || b==0) {
		if(q==1 ){
			int pos = lower_bound(num+1, num+m+1, b)-num;
			if(pos>m || num[pos]!= b) printf("inf\n");
			else printf("0\n");
		} else if(q==-1 ){
			int pos = lower_bound(num+1, num+m+1, b)-num;
			int pos2 = lower_bound(num+1, num+m+1, -b)-num;
			int p=0;
			if(pos>m || num[pos]!=b || pos2>m || num[pos2]!=-b){
				printf("inf\n");
			} else {
				printf("0\n");
			}
		} else if(q==0){
			int pos = lower_bound(num+1, num+m+1, 0)-num;
			if(pos>m || num[pos]!=0) printf("inf\n");
			else {
				int pos2 = lower_bound(num+1, num+m+1, b)-num;
				if(pos2>m || num[pos2]!=b) printf("1\n");
				else printf("0\n");
			}
		} else if(b==0){
			int pos = lower_bound(num+1, num+m+1, 0)-num;
			if(pos>m || num[pos]!=0) printf("inf\n");
			else printf("0\n");
		}
	}
	else {
		__int64 n=0;
		__int64 u = b;
		while(abs(u)<=l){
			int pos = lower_bound(num+1, num+m+1, u)-num;
			if(pos>m || num[pos]!=u ) n++;
			u*=q;
			if(u==b)break;
		}
		printf("%I64d\n", n);
	}
	return 0;
}

C.
  
                                                                            Functions again
题意:
      
                                              给定一组数据,(顺序不可变),根据上述公式求出f的最大值.
求解:
          先将|a[i]-a[i+1]|的序列p求出来, 根据f方程式
          容易知道, 总共只有两种情况,
         1.    p中下标为奇数的数*-1,  p中下标为偶数的数*1;
         2.    p中下标为奇数的数*1,  p中下标为偶数的数*-1;
  
故只需要进行两次遍历数组, 并采用最大连续和的算法解决.  注意此题数据较大,应开long long 或者 __int64
Code:
        
#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
#include<string>
#include<queue>
#include<stack>
using namespace std;
const int maxn = 100005;
__int64 num[maxn];
int main()
{
	__int64 n;
	scanf("%I64d", &n);
	__int64 x, y, len=0;
	for(int i=1; i<=n; i++){
		scanf("%I64d", &x);
		if(i==1) y=x;
		else {
			num[len++] = abs(y-x);
			y=x;
		}
	}
	__int64 p = 1;
	__int64 sum=0;
	__int64 MAX = -1;
	for(__int64 i=0; i<len; i++){
		if(i%2==0) p=1;
		else p=-1;
		sum += p*num[i];
		if(sum>MAX){
			MAX = sum;
		}
		if(sum<0) sum=0;
	}
	sum = 0;
	for(__int64 i=0; i<len; i++){
		if(i%2!=0) p=1;
		else p=-1;
		sum += p*num[i];
		
		if(sum>MAX){
			MAX = sum;
		}
		if(sum<0) sum=0;
	}
	printf("%I64d\n", MAX);
	return 0;
}



D:
                                                                                 Weird journey
题意:
       求是否有一条路径可以经过所有的道路, 且有m-2道路被经过两次, 其余2条道路只经过一次。(城市与城市之间的道路, 以及城市与本身的自环道路),  输出满足条件的路径的数目
求解:
      先确定是否有一条路径可以满足条件, 只需判断是否所有的道路都是互通的
     然后, 分析可知, 只经过一次的两条道路的可能情况如下:
     1.两条道路均为自环道路
     2.一条为自环道路, 另一条为不同城市之间的道路
     3.两条均为 不同城市之间的道路(注意:这两条道路必须是相邻的, 否则无法满足条件)
Code:
    
#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
#include<vector>
using namespace std;
typedef __int64 (ll);
const int maxn = 1e6+50;
int fa[maxn], u[maxn], v[maxn];
bool vis[maxn];
ll flag[maxn];
ll d[maxn];
ll find(int x){
	if(fa[x]==x) return x;
	else return (fa[x]=find(fa[x]));
}
void Unit(int a, int b){
	int f1 = find(a);
	int f2 = find(b);
	if(f1!=f2) fa[f1]=f2;
	return ;
}
int main()
{
	int i, j, a, b, len=0;
	ll n, m, cnt1=0, cnt2=0;
	memset(d, 0, sizeof(d));
	memset(vis, 0, sizeof(vis));
	scanf("%I64d %I64d", &n, &m);
	for(i=1; i<=n; i++) fa[i]=i;
	for(i=1; i<=m; i++){
		scanf("%d %d", &a, &b);
		u[i]=a,v[i]=b;
		if(a==b) cnt1++;
		else{
			d[a]++;
			d[b]++;
			cnt2++;
			Unit(a, b);
		}
	}
	int em = find(u[1]);
	bool flag=true;
	//判断所有的边是否都互通 
	for(i=2; i<=m; i++) {
		int f;
		if(!vis[u[i]]) f=find(u[i]);
		if(find(!vis[v[i]])) f=find(v[i]);
		vis[u[i]] = vis[v[i]] = 1;
		f=find(u[i]);
		if(f!=em){
			flag=false;	
			break;
		} 
	}
	if(!flag){
		printf("0\n");
	} else {
		ll ans=0;
		ans += cnt1*cnt2;//自环边与非自环边 
		ans += cnt1*(cnt1-1)/2;//自环边与自环边 
		for(i=1; i<=n; i++)//非自环边与非自环边 
		{
			ans += d[i]*(d[i]-1)/2;
		}
		printf("%I64d\n", ans); 
	}
} 


       

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值