A 平方的平均值
题目链接:http://code.bupt.edu.cn/problem/p/442/
思路:超级大水题了,我都无语了,要注意到xi可能取负数,然后就没什么问题了,比赛的时候没有注意到一个int转long long
先上wa的代码:
#include <iostream>
#include <cstring>
#include <cstdlib>
#include<cstdio>
#include <algorithm>
#include <vector>
#define INF 10000000000
#define eps 1e-9
using namespace std;
const int MAX_E=200100;
const int MAX_N=10000005;
int main()
{
int n,a;//这个地方应该开long long
long long mid;
while(scanf("%d",&n)!=EOF){
if(n==0){
printf("0\n");
continue;
}
scanf("%d",&a);
mid=a*a;
for(int i=1;i<n;i++){
scanf("%d",&a);
if(a*a<mid) mid=a*a;
}
printf("%lld\n",mid);
}
return 0;
}
A的代码:
#include <iostream>
#include <cstring>
#include <cstdlib>
#include<cstdio>
#include <algorithm>
#include <vector>
#define INF 10000000000
#define eps 1e-9
using namespace std;
const int MAX_E=200100;
const int MAX_N=10000005;
int main()
{
int n;
long long a;
long long mid;
while(scanf("%d",&n)!=EOF){
if(n==0){
printf("0\n");
continue;
}
cin>>a;
mid=a*a;
for(int i=1;i<n;i++){
cin>>a;
if(a*a<mid) mid=a*a;
}
printf("%lld\n",mid);
}
return 0;
}
B 立方体
题目链接:http://code.bupt.edu.cn/problem/p/431/
大致思路:先找到与待求点对应的点(这个点到其他点的距离和最短),再找得到其相邻的三个点(这三点到这个点的距离相等),再通过一个向量加法就可以求出来待求点。
比赛的时候剩的时间太少了,当时脑子还特别乱就没做出来,后来做的时候wa了好多次,这主要是因为dis用了double,应该不算他的开方,直接平方来比较。
code:
#include <iostream>
#include <cstring>
#include <cstdlib>
#include<cstdio>
#include <algorithm>
#include <vector>
#include <cmath>
#define INF 99999999
#define eps 1e-9
using namespace std;
const int MAX_E=200100;
const int MAX_N=10;
struct pos{int x,y,z;} P[MAX_N];
long long tt[MAX_N];
int cc[MAX_N];
long long dis(pos A,pos B)
{
long long res;
res=(A.x-B.x)*(A.x-B.x)+(A.y-B.y)*(A.y-B.y)+(A.z-B.z)*(A.z-B.z);
return res;
}
int main()
{
int nn,m,T;
long long midnn;
pos dd;
scanf("%d",&T);
while(T--){
midnn=0;
m=0;
for(int i=0;i<7;i++) scanf("%d%d%d",&P[i].x,&P[i].y,&P[i].z);
memset(tt,0,sizeof(tt));
for(int i=0;i<7;i++){
for(int j=0;j<7;j++){
if(j==i) continue;
tt[i]+=dis(P[i],P[j]);
}
if(midnn==0) {midnn=tt[i];nn=i;}
else if(tt[i]<midnn){
midnn=tt[i];
nn=i;
}
}
midnn=0;
for(int i=0;i<7;i++){
if(i==nn) continue;
if(midnn==0){
midnn=dis(P[nn],P[i]);
cc[m++]=i;
}
else if(midnn==dis(P[nn],P[i])) cc[m++]=i;
}
dd.x=(P[cc[0]].x-P[nn].x)+(P[cc[1]].x-P[nn].x)+(P[cc[2]].x-P[nn].x);
dd.y=(P[cc[0]].y-P[nn].y)+(P[cc[1]].y-P[nn].y)+(P[cc[2]].y-P[nn].y);
dd.z=(P[cc[0]].z-P[nn].z)+(P[cc[1]].z-P[nn].z)+(P[cc[2]].z-P[nn].z);
printf("%d %d %d\n",dd.x+P[nn].x,dd.y+P[nn].y,dd.z+P[nn].z);
}
}
C 字符重排
题目链接:http://code.bupt.edu.cn/problem/p/432/
思路:自己想了一种贪心的算法,就是想先把字符串按降序排列,然后再从头开始一个一个取,一开始超时,后来自己有加了一个队列优化,wa,发现了一个无法解决的bug。
看了学长的标程有了一个更好的贪心算法:先统计每个字符出现的次数,如果最大次数大于l(表示字符串的长度)就直接返回-1,之后判断剩余长度是否是奇数,如果是奇数且存在一个字符出现的次数等于剩余长度+1除以二,则此次添加此字符,否则选择一个最靠前的字符添加。
学长的标程写的真是优美,参照的写了一个(太优美了,简洁的不能再简洁了)。
code:
#include<bits/stdc++.h>
using namespace std;
char a[100005],b[100005];
int nn[26];
void solve()
{
int l=strlen(a),maxnn=0;
memset(nn,0,sizeof(nn));
for(int i=0;i<l;i++) maxnn=max(maxnn,++nn[a[i]-'a']);
if(maxnn>(l+1)/2){
printf("-1\n");
return ;
}
int pre=-1;
for(int k=0;k<l;k++){
int flag=0,ii=-1;
for(int i=0;i<26;i++){
if(((l-k)&1)&&nn[i]==(l-k+1)/2) flag=1,ii=i;
else if(!flag&&nn[i]&&ii==-1&&i!=pre) ii=i;
}
b[k]=ii+'a';
nn[ii]--;
pre=ii;
}
b[l]='\0';
printf("%s\n",b);
}
int main()
{
int T;
scanf("%d",&T);
while(T--){
scanf("%s",a);
solve();
}
return 0;
}
D Fibnacci
链接:http://code.bupt.edu.cn/problem/p/433/
思路:因为数据规模比较大,所以直接用递推式肯定超时,给的内存也开不了那么大的数组。就用矩阵快速幂的方法来快速计算递推式。
由于这个还不是裸的 Fibnacci,所以得给式子做一个变形:f(n)=f(n-1)+f(n-2)+n <=> f(n)+n=f(n-1)+n-1+f(n-2)+n-2+3 <=> Tn=Tn-1+Tn-2+3
再用矩阵快速幂就可以做出来了,取模的时候可能会出现负数的情况(在这个里卡了好长时间),还好最后发现了。
code:
#include <iostream>
#include <cstring>
#include <cstdlib>
#include<cstdio>
#include <algorithm>
#include <vector>
#define INF 10000000000
#define eps 1e-9
using namespace std;
const int MAX_E=200100;
const int MAX_N=10000005;
typedef vector<long long> a;
typedef vector<a> b;
const long long M=1000000007;
b mul(b &A,b &B)
{
b C(A.size(),a(B[0].size()));
for(int i=0;i<A.size();i++){
for(int k=0;k<B.size();k++){
for(int j=0;j<B[0].size();j++){
C[i][j]=(C[i][j]+A[i][k]*B[k][j])%M;
}
}
}
return C;
}
b pow(b A,long long n)
{
b B(A.size(),a(A.size()));
for(int i=0;i<A.size();i++) B[i][i]=1;
while(n>0){
if(n&1) B=mul(B,A);
A=mul(A,A);
n>>=1;
}
return B;
}
int main()
{
int t;
long long n;
scanf("%d",&t);
b A(3,a(3));
while(t--){
cin>>n;
A[0][0]=A[0][1]=A[0][2]=1;
A[1][0]=1;A[1][1]=A[1][2]=0;
A[2][0]=A[2][1]=0;A[2][2]=1;
A=pow(A,n);
long long res=2*A[1][0]+A[1][1]+3*A[1][2];
if(res<n) res+=M; //防止出现负数!!!
printf("%lld\n",(res-n)%M);
}
}