传送门:http://codeforces.com/contest/454
这场比赛做的virtual,在家里面根本没法做CF,老妈连我白天碰一下电脑都要叨叨叨叨叨叨说半天,11点30做……简直hehe
出了3题,题数还行,但是B题WA太久了……不应该。
A题
一个简单的图形打印题,要求打印一个菱形,N为奇数,数好‘*’的个数,把图形分成两半打出来即可。
#include <iostream>
#include <cstring>
#include <cstdio>
using namespace std;
int main(){
int n;
cin>>n;
int std=(n+1)/2;
for (int i=1;i<std;i++){
for (int j=1;j<=std-i;j++) cout<<"*";
for (int j=std-i+1;j<=n-(std-i);j++) cout<<"D";
for (int j=1;j<=std-i;j++) cout<<"*";
cout<<endl;
}
for (int i=1;i<=n;i++) cout<<"D";
cout<<endl;
for (int i=std-1;i>=1;i--){
<span style="white-space:pre"> </span>for (int j=1;j<=std-i;j++) cout<<"*";
for (int j=std-i+1;j<=n-(std-i);j++) cout<<"D";
for (int j=1;j<=std-i;j++) cout<<"*";
cout<<endl;
}
return 0;
}
B题
题目大意是给定一个序列,每次操作只能把最后一个数字移动到第一个位置,求最少多少次操作可以使得序列变为一个不下降序列。
抽象出来也即给一个环,找一个起点使得整个序列为不下降序列。
这道题貌似hack得相当欢乐,我第一次提交WA在了第二十多组数据上……一下子就无语了
首先,我们考虑有可行解的情况:因为要求是不下降序列,所以第一个元素一定是最小的那一个,假设这个最小值的位置是p(1..N编号),那么可以知道,要么p==1时,不动,要么p!=1时,移动n-p+1次。
所以,有解的情况是非常容易的。
接下来是判断无解,有两种想法:
1、最小值肯定是在要求生成序列的第一个,那么从最小值开始,把整个序列写出来,检查一次即可。第一次交就是这种方法,跪在了第22组测试数据,想必是hack的数据。很快想到了跪舔的原因,“不下降”暗示着元素是可以有相等的,当最小值出现多个时,应该以每一个都为起点检查一次(先检查后出现的最小值以保证步数最小),成功则直接输出,否则继续检查。但是考虑到极端情况(212121212121212121………………)的时间复杂度,GG。
2、现在的目的相当于是把这个数列砍成两段,然后把前一段放在后一段的后面,使得新生成的序列满足要求。
也就是说:(1)两段都是不下降序列(2)a[1]>=a[n]
===>满足(1)不下降序列超过2个(2)a[1]<a[n]中任意一个,都是无解的
时间复杂度很低,完全满足需求。
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
int a[100000+20];
int main(){
int n;
cin>>n;
for (int i=1;i<=n;i++){
cin>>a[i];
}
a[n+1]=-1;
int p=0;
for (int i=1;i<=n;i++){
if (a[i]>a[i+1]){
p=i;
break;
}
}
if (p==n){
cout<<0<<endl;
}
else {
int flag=0;
for (int i=p+1;i<n;i++){
if (a[i]>a[i+1]){
flag=1;
break;
}
}
if (flag==1){
cout<<-1<<endl;
}
else {
if (a[1]>=a[n]){
cout<<n-p<<endl;
}
else {
cout<<-1<<endl;
}
}
}
return 0;
}
C题
一个推公式的题,做得比较顺利,懒得传公式的图,直接代码表示:
for(int i=1; i<=m; ++i) {
sum = pow((i-1.0)/m, n*1.0);
ans += (pow(i*1.0/m, n*1.0)-sum)*i;
}
保留12位小数输出就行了。对于这种题,我只想说,幸好不是poj
#include <iostream>
#include <cstring>
#include <cmath>
#include <cstdio>
#include <algorithm>
using namespace std;
int main(void) {
int m, n;
scanf("%d%d",&m,&n);
double ans = 0.0;
double sum = 0.0;
for(int i=1; i<=m; ++i) {
sum = pow((i-1.0)/m, n*1.0);
ans += (pow(i*1.0/m, n*1.0)-sum)*i;
}
printf("%.12lf\n",ans);
return 0;
}