A.简单求和 POJ1844
题目大意
找出最小的n,使对于给定的
成立。
思路
首先知n的必要条件为
所以当我们从n=1(或n=⌈1+8×S√−12⌉,取满足∑i≥S的下界,解二元一次方程得,但是开方的时间开销大于枚举)向上枚举,当Sn≥S且Sn−Smod2=0时,即为我们所求最小的的n。
代码
#include<cstdio>
int main()
{
int S, i;
scanf("%d",&S);
for(i=1;;i++)
if((i*(i+1)/2-S)>=0 && (i*(i+1)/2-S)%2==0){
printf("%d\n",i);
break;
}
return 0;
}
B.悉宇大大的问题 CodeForces707C
题目大意
输入一个整数
思路
易知当n=1,2时,无法找到满足题意的m,k。
当n>2时,由于答案可能有多种情况,那么不妨设n<m<k,即有n2+m2=k2。很容易联想到平方差公式,化为n2=(k+m)×(k−m)。寻找规律发现(3,4,5),(5,12,13),(7,24,25),…, 即当n为奇数时,有
由此,同样的思路,当n为偶数时,令
由于此题中m,k超出int的取值范围,所以需要用long long int。
代码
#include<cstdio>
#include<cstdio>
typedef long long ll;
int main()
{
ll n,m,k;
scanf("%I64d",&n);
if(n==1 || n==2){
printf("-1\n");
return 0;
}
if(n%2){
m=(n*n-1)/2;
k=(n*n+1)/2;
}
else{
m=n*n/4-1;
k=n*n/4+1;
}
printf("%I64d %I64d\n",m,k);
return 0;
}
C.老陶的幸福生活 HDU1273
题目大意
一个节点数为N(0<N≤109)的无向完全图,每条边只能走一次。求有多少个经过每一个点的回路。
思路
对于节点数为N的无向完全图,每个节点度数为
注:对于过程的有效性,每条回路使得每个点的度数减2。所以整个图在第
代码
#include<cstdio>
int main()
{
int n;
while(scanf("%d",&n),n)
printf("%d\n",(n-1)/2);
return 0;
}
D.小朋友吃汉堡 UVA557
题目大意
有偶数k(k=2,4,⋯,105)个小朋友,通过掷硬币的方法吃各有n=k/2个的两种汉堡,如果结果为正,吃第一种汉堡,否则吃第二种汉堡。中途若一种被吃完则不再掷。求最后两人吃到同一种汉堡的概率。
思路
求反面——最后两人吃到不同汉堡的情况,那么除了最后一个汉堡外,都进行了一次投掷。可知选取汉堡的情况数为2×Cn−12n−2种(由于最后两个汉堡的排列是两种),而每种出现的概率相等,为0.52n−1。那么可知最后两人吃到不同汉堡的概率为p[n]=Cn−12n−2/ 22n−2。由于直接计算会超出double的有效范围,且计算组合数时间复杂度过大,将前后概率相除化为递推式,有p[n+1]=p[n]×(1−0.5/i)。
最后输出1−p[k/2]即可。
代码
#include<cstdio>
const int MAXN=50005;
double f[MAXN];
int main()
{
f[1]=1;
for(int i=1;i<MAXN-1;i++)
f[i+1]=f[i]*(1-0.5/i);
int n,i;
scanf("%d",&n);
while(n--){
scanf("%d",&i);
printf("%.4lf\n",1-f[i/2]);
}
return 0;
}
E.舞台灯光问题 CodeForces738B
题目大意
在由n×m(1≤n,m≤1000)个方格组成的长方形中,至少有一名演员在方格上。如果在某一个方格没有演员,且在此位置放置聚光灯后,在上下左右某个朝向上有演员,那么就称这是个好位置。如果两个位置的所处方格不同或聚光灯朝向不同,则认为两个位置是不同的。求好位置的总数。
思路
考虑时间复杂度为O(n2)的方法。如果在一行内依次枚举,一旦有演员出现,那么其后的空地都可以放置聚光灯向左照射。同理,如果在一行内逆向枚举,一旦有演员出现,那么其后的空地都可以放置聚光灯向右照射。在列上亦是。
代码
#include<cstdio>
const int MAXN=1005;
int mat[MAXN][MAXN];
int main()
{
int n,m,sum=0;
scanf("%d%d",&n,&m);
for(int i=0;i<n;i++)
for(int j=0;j<m;j++)
scanf("%d",&mat[i][j]);
for(int i=0;i<n;i++){
bool vl=false,vr=false; //vl=ValidLeft,vr=ValidRight
for(int j=0;j<m;j++){
if(mat[i][j])
vr=true;
else if(vr)
sum++;
}
for(int j=m-1;j>=0;j--){
if(mat[i][j])
vl=true;
else if(vl)
sum++;
}
}
for(int j=0;j<m;j++){
bool vu=false,vd=false; //vu=ValidUp,vd=ValidDown
for(int i=0;i<n;i++){
if(mat[i][j])
vd=true;
else if(vd)
sum++;
}
for(int i=n-1;i>=0;i--){
if(mat[i][j])
vu=true;
else if(vu)
sum++;
}
}
printf("%d\n",sum);
return 0;
}
F-Boss买披萨 CodeForces731B
题目大意
有一个长度为n(1≤n≤2×105)的数组ai(0≤ai≤104),问能否对数组经过如下处理后,使整个数组中的数都化为0。
1. a[i]减去任意偶数个数
2. a[i]−−且 a[i+1]−−
思路
考虑空间复杂度O(1)的方法。设置布尔变量owned表示上一个数是否为奇数,初始化为false。然后依次读入,若ai=0且owned=true那么是不可能实现的,直接输出并跳出。否则,若owned=true那么ai需要减1。考察这时的
最后只需考察运行完后owned的值是否为false即可。
代码
#include<cstdio>
int main()
{
int n,a;
bool owned=false,flag=true;
scanf("%d",&n);
for(int i=1;i<=n;i++){
scanf("%d",&a);
if(!a&&owned){
printf("NO\n");
return 0;
}
if(owned)
a--;
if(a%2)
owned=true;
else
owned=false;
}
if(!owned)
printf("YES\n");
else
printf("NO\n");
return 0;
}