转载请注明出处,谢谢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;
}