2014 BUPT 新生排位赛05

平方的平均值

题目链接: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);
    }
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值