Codeforces Round #129 (Div. 2)

转载请注明出处,谢谢http://blog.csdn.net/ACM_cxlove?viewmode=contents by---cxlove

没想到提交的4题都过了, 第一次,rate也涨了,终于紫了。

总结:小错误太多

A:问距离最近的城市是不是唯一。唯一则输出标号,就是个排序

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
#include<vector>
#include<cmath>
#include<string>
#define inf 1<<30
#define eps 1e-7
#define LD long double
#define LL long long
using namespace std;
struct Node{
	int idx,num;
}a[100005];
bool cmp(Node n1,Node n2){
	return n1.num<n2.num;
}
int main(){
	int n;
	while(scanf("%d",&n)!=EOF){
		for(int i=0;i<n;i++){
			scanf("%d",&a[i].num);
			a[i].idx=i+1;
		}
		if(n==1){
			printf("1\n");
			continue;
		}
		sort(a,a+n,cmp);
		if(a[0].num==a[1].num)
			printf("Still Rozdil\n");
		else
			printf("%d\n",a[0].idx);
	}
	return 0;
}

B:每次可以选择位置i后的所有数加1,则最少要做多少次操作,使得数列非递减。

最少操作肯定是保证后者不比前者小即可。

从头到尾遍历,不需要做一次操作, 把之后的所有数都加1,相邻之间的相对差不变。唯一一个1A。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
#include<vector>
#include<cmath>
#include<string>
#define inf 1<<30
#define eps 1e-7
#define LD long double
#define LL __int64
using namespace std;
int a[100005];
int main(){
	int n;
	while(scanf("%d",&n)!=EOF){
		for(int i=0;i<n;i++)
			scanf("%d",&a[i]);
		LL ans=0;
		for(int i=1;i<n;i++)
			if(a[i]<a[i-1])
				ans+=a[i-1]-a[i];
		printf("%I64d\n",ans);
	}
	return 0;
}

C:头尾相同的数称为XX数,问区间[l,r]有多少个XX数。预处理+瞎搞,其实有很简单的做法,直接得到公式,弱爆了。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
#include<vector>
#include<cmath>
#include<string>
#define inf 1<<30
#define eps 1e-7
#define LD long double
#define LL __int64
using namespace std;
LL l,r;
LL dp[20];
LL sum[20]; 
int countdigit(LL num){
	int ans=0;
	while(num){
		num/=10;
		ans++;
	}
	return ans;
}
int firstdigit(LL num){
	while(num>=10)
		num/=10;
	return num;
}
int lastdigit(LL num){
	return num%10;
}
int main(){
	dp[1]=dp[2]=9;
	sum[1]=10;sum[2]=100;
	LL tmp=10;
	for(int i=3;i<20;i++){
		dp[i]=9*tmp;
		tmp=tmp*10;
		sum[i]=sum[i-1]*10;
	}
	while(scanf("%I64d%I64d",&l,&r)!=EOF){
		int a=countdigit(l);
		int b=countdigit(r);
		LL ans=0;
		for(int i=a+1;i<=b;i++)
			ans+=dp[i];
		int first=firstdigit(l);
		int last=lastdigit(l);
		if(a==1){
			ans+=10-first;
		}
		else if(a==2){
			ans+=9-first;
			if(first>=last)
				ans++;
		}
		else{
			if(first>=last){
				ans+=sum[a-2]-(l/10)%sum[a-2];
				for(int i=first+1;i<=9;i++)
					ans+=sum[a-2];
			}
			else{
				for(int i=first+1;i<=9;i++)
					ans+=sum[a-2];
				ans+=sum[a-2]-(l/10)%sum[a-2]-1;
			}
		}
		first=firstdigit(r);
		last=lastdigit(r);
		if(b==1){
			ans-=9-last;
		}
		else if(b==2){
			ans-=9-first;
			if(last<first)
				ans--;
		}
		else{
			if(first>last){
				ans-=sum[b-2]-(r/10)%sum[b-2];
				for(int i=first+1;i<=9;i++)
					ans-=sum[b-2];
			}
			else{
				ans-=sum[b-2]-((r/10)%sum[b-2]+1);
				for(int i=first+1;i<=9;i++)
					ans-=sum[b-2];
			}
		}
		printf("%I64d\n",ans);
	}
	return 0;
}

D:n张牌,牌的两面有颜色,最少多少次操作使得某种颜色朝上的数量超过半数,map或者离散化

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
#include<vector>
#include<cmath>
#include<map>
#include<string>
#define inf 1<<30
#define eps 1e-7
#define LD long double
#define LL __int64
#define maxn 1000000005
using namespace std;
map<int,int>m1;
map<int,int>m2;
int main(){
    int n,u,v;
    scanf("%d",&n);
    int ans=n+10;
    for(int i=0;i<n;i++){
        scanf("%d%d",&u,&v);
        if(u!=v)
            m1[u]++;
        m1[v]++;m2[u]++;
        if(m1[u]>=(n+1)/2)
            ans=min(ans,max(0,(1+n)/2-m2[u]));
        if(m1[v]>=(n+1)/2)
            ans=min(ans,max(0,(1+n)/2-m2[v]));
    }
    if(ans>n)
       printf("-1\n");
    else
       printf("%d\n",ans);
    return 0;
}

E:概率题,对于每一组a[i]==b[j],判断出现在多少个子集内,当时看错题目了,错误理解了子集的概念。膜拜詹姐

#include<iostream>
#include<cstdio>
#include<cstring>
#define LD long double
#define LL __int64
#define M 200005
int n;
char str1[M],str2[M];
int main(){
	while(scanf("%d%s%s",&n,str1,str2)!=EOF){
		LD ans=0;
		for(int ch='A';ch<='Z';ch++){
			int j=n-1;
			LD p=0;
			for(int i=n-1;i>=0;i--){
				if(str1[i]==ch){			
					while(j>i){
						if(str2[j]==ch)
							p+=n-j;
						j--;
					}
					ans+=p*(i+1);
				}
			}
			j=n-1;
			p=0;
			for(int i=n-1;i>=0;i--){
				if(str2[i]==ch){				
					while(j>=i){
						if(str1[j]==ch)
							p+=n-j;
						j--;
					}
					ans+=p*(i+1);
				}
			}
		}
		printf("%.10f\n",(LD)ans*6/((LD)n*(n+1)*(2*n+1)));
	}
	return 0;
}
	


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值