BestCoder Round #54 (div.2)

来源:互联网 发布:no surprises知乎 编辑:程序博客网 时间:2024/05/16 05:41

好久没写博客来。

1001 排序题

首先就是字符串处理,小心空格就可以了 用整行读入。水题。用了8分钟搞定

#include<cstdio>#include<cstring>#include<cmath>#include<cstdlib>#include<ctime>#include<iostream>#include<algorithm>#include<sstream>#include<fstream>#include<vector>#include<map>#include<stack>#include<list>#include<set>#include<queue>#define LL long long#define lson l,m,rt<<1#define rson m+1,r,rt<<1 | 1/*正反循环的宏定义*/#define ffr(i,x,y) for(int i=(x),_en=(y);i<=_en;i++)#define rff(i,x,y) for(int i=(x),_en=(y);i>=_en;i--)#define clr(f,z) memset(f,z,sizeof(f))using namespace std;const int maxn=100005,inf=1<<29;int dir[][2]={ {0,1},{-1,0},{0,-1},{1,0},{-1,1},{-1,-1},{1,-1},{1,1}};//常用方向数组int n,m,t;//常用全局变量struct node{    string s;    int num;}a[maxn];//常用结构体vector<int>G[maxn];//常用邻接表bool cmp(node a,node b)//常用排序规则{    return a.num>b.num;}/*函数重载,可根据参数类型,自动选择输入*/bool sf(int &x) { return scanf("%d",&x)==1;}bool sf(char *x){return scanf("%s",x)==1;}bool sf(double &x){return scanf("%lf",&x)==1;}bool sf(LL &x) { return scanf("%I64d",&x)==1;}void pf(int x,int op) {    op?printf("%d\n",x):printf("%d ",x);//op==0打印数字加空格,op==1打印数字加换行}int get_rand(int n){    return (int)((double)rand() / RAND_MAX * n) ;}int main(){     //freopen("in.txt","r",stdin);     //freopen("out.txt","w",stdout);     //srand(time(NULL));    sf(t);    while(t--)    {        sf(n);        string s;        getline(cin,s);        ffr(i,0,n-1)        {            getline(cin,s);            int len=s.size();            a[i].s=s.substr(0,len-5);//取出字符串部分            a[i].num=(s[len-4]-'0')*1000+(s[len-3]-'0')*100+(s[len-2]-'0')*10+(s[len-1]-'0')*1;//取出年份            //cout<<a[i].s<<" "<<a[i].num<<endl;        }        sort(a,a+n,cmp);        ffr(i,0,n-1) cout<<a[i].s<<endl;    }    return 0;}

1002  给定n个数,这n个数相乘有一个乘积,现在要你找出这个乘积的最小因子,这个因子约数最少要有3个,约数包括本身。

虽然我们不能算出这个乘积,但是我们可以对每个数进行分解质因数。然后取最小的两个质因数出来相乘即为满足题目要求的最小因子。

首先,因为最小的两个质因数相乘的结果可以保证,它约数最少是3个,而且它必然是最小因子(所有满足约数个数大于等于3的最小因子)。

为了方便起见,我们可以把分解出来的质因数统一放到一个动态数组里,分解完所有数之后,只需排序那个存放质因数的数组,取最小的两个因子即可。如果动态数组元素个数小于2,那显然不存在解。。。

#include<cstdio>#include<algorithm>#include<cmath>#include<cstring>#include<vector>#include<map>#include<iostream>#define LL long longusing namespace std;const int L=100005,inf=1<<30,maxn=1005;int prime[L],np=0;bool is[L];vector<int>ans;void getPrime()//筛法求素数{    fill(is,is+L,1);    is[1]=0;    for(int i=2;i<L;i++)        if(is[i])        {            prime[++np]=i;            for(int j=2*i;j<L;j+=i) is[j]=0;        }   // for(int i=1;i<=np;i++)        //cout<<prime[i]<<" ";}bool is_prime(int n)//素数判定{    for(int i=1;prime[i]*prime[i]<=n;i++)        if(n%prime[i]==0) return 0;    return 1;}vector<int> divisor(int n)//求约数{    vector<int>ans;    for(int i=1;i*i<=n;i++)        if(n%i==0)        {            ans.push_back(i);            if(i*i!=n) ans.push_back(n/i);        }    return ans;}void factor(int n)//因式分解{    //map<int,int>ans;    for(int i=1;prime[i]*prime[i]<=n;i++)    {        while(n%prime[i]==0)        {            //ans[prime[i]]++;            ans.push_back(prime[i]);            n/=prime[i];        }    }    if(n!=1) ans.push_back(n);    //return ans;}int main(){    getPrime();    int n,t;    cin>>t;    while(t--)    {        ans.clear();        cin>>n;        for(int i=0;i<n;i++)        {            int x;            cin>>x;            factor(x);//分解质因数        }        if(ans.size()<2) puts("-1");        else        {            sort(ans.begin(),ans.end());            LL res=(LL)ans[0]*ans[1];//取最小的两个因子            printf("%I64d\n",res);        }    }    return 0;}

1003

1003 是题意理解得不够透彻,而导致程序漏了一种情况,就是n个数全为0的时候是等比数列,而我们一开始认为,数列长度大于2的时候一旦有0就一定不是等比数列,事实上只有当数列长度大于等于2,数列存在0且不全为0才不是等比数列。所以,程序要先处理好0的问题,然后扫一遍是否每个数a[i]都满足,a[i-1]*a[i+1]=a[i]*a[i]就可以了,也不难。

JAVA版AC代码来一发

import java.util.*;import java.math.*;import java.io.*;public class Main {static Scanner cin=new Scanner(System.in);static public void main(String args[]){BigInteger a,b,c[]=new BigInteger[105],z=BigInteger.ZERO;int t=cin.nextInt(),n;while(t>0){t--;n=cin.nextInt();for(int i=1;i<=n;i++) c[i]=cin.nextBigInteger(); boolean f=true,all=true,only=false;for(int i=1;i<=n;i++)if(c[i].equals(z)) only=true;else all=false;if(all) {System.out.println("Yes");continue;}if(only) {System.out.println("No");continue;}for(int i=2;i<=n-1;i++)if(c[i-1].multiply(c[i+1]).equals(c[i].multiply(c[i]))==false) f=false; if(f==false) System.out.println("No");else System.out.println("Yes");}}}

当然少不了C++版的

#include <iostream>#include <cstdio>#include <algorithm>#include <cstring>#include <cmath>#include <map>#include <queue>#include <set>#include <vector>using namespace std;#define L(x) (1 << (x))const double PI = acos(-1.0);const int Maxn = 10015;double ax[Maxn], ay[Maxn], bx[Maxn], by[Maxn];char sa[Maxn/2],sb[Maxn/2];int sum[Maxn];int x1[Maxn],x2[Maxn];int revv(int x, int bits){    int ret = 0;    for (int i = 0; i < bits; i++)    {        ret <<= 1;        ret |= x & 1;        x >>= 1;    }    return ret;}void fft(double * a, double * b, int n, bool rev){    int bits = 0;    while (1 << bits < n) ++bits;    for (int i = 0; i < n; i++)    {        int j = revv(i, bits);        if (i < j)            swap(a[i], a[j]), swap(b[i], b[j]);    }    for (int len = 2; len <= n; len <<= 1)    {        int half = len >> 1;        double wmx = cos(2 * PI / len), wmy = sin(2 * PI / len);        if (rev) wmy = -wmy;        for (int i = 0; i < n; i += len)        {            double wx = 1, wy = 0;            for (int j = 0; j < half; j++)            {                double cx = a[i + j], cy = b[i + j];                double dx = a[i + j + half], dy = b[i + j + half];                double ex = dx * wx - dy * wy, ey = dx * wy + dy * wx;                a[i + j] = cx + ex, b[i + j] = cy + ey;                a[i + j + half] = cx - ex, b[i + j + half] = cy - ey;                double wnx = wx * wmx - wy * wmy, wny = wx * wmy + wy * wmx;                wx = wnx, wy = wny;            }        }    }    if (rev)    {        for (int i = 0; i < n; i++)            a[i] /= n, b[i] /= n;    }}int solve(int a[],int na,int b[],int nb,int ans[]){    int len = max(na, nb), ln;    for(ln=0; L(ln)<len; ++ln);    len=L(++ln);    for (int i = 0; i < len ; ++i)    {        if (i >= na) ax[i] = 0, ay[i] =0;        else ax[i] = a[i], ay[i] = 0;    }    fft(ax, ay, len, 0);    for (int i = 0; i < len; ++i)    {        if (i >= nb) bx[i] = 0, by[i] = 0;        else bx[i] = b[i], by[i] = 0;    }    fft(bx, by, len, 0);    for (int i = 0; i < len; ++i)    {        double cx = ax[i] * bx[i] - ay[i] * by[i];        double cy = ax[i] * by[i] + ay[i] * bx[i];        ax[i] = cx, ay[i] = cy;    }    fft(ax, ay, len, 1);    for (int i = 0; i < len; ++i)        ans[i] = (int)(ax[i] + 0.5);    return len;}string mul(string sa,string sb){    int l1,l2,l;    int i;    string ans;    memset(sum, 0, sizeof(sum));    l1 = sa.size();    l2 = sb.size();    for(i = 0; i < l1; i++)        x1[i] = sa[l1 - i - 1]-'0';    for(i = 0; i < l2; i++)        x2[i] = sb[l2-i-1]-'0';    l = solve(x1, l1, x2, l2, sum);    for(i = 0; i<l || sum[i] >= 10; i++) // 进位    {        sum[i + 1] += sum[i] / 10;        sum[i] %= 10;    }    l = i;    while(sum[l] <= 0 && l>0)    l--; // 检索最高位    for(i = l; i >= 0; i--)    ans+=sum[i] + '0'; // 倒序输出    return ans;}string ssa[Maxn];bool zero(string s){    int num=0;    for(int i=0;i<s.size();i++)    {        num=num*10+s[i]-'0';        if(num) return 0;    }    return 1;}int main(){    cin.sync_with_stdio(false);    string a,b;    int t,n;    cin>>t;    while(t--)    {        cin>>n;        for(int i=1;i<=n;i++) cin>>ssa[i];        bool f=1,all=true,only=false;        for(int i=1;i<=n;i++)            if(zero(ssa[i])) only=true;            else all=false;        if(all)        {            puts("Yes");            continue;        }        if(only)        {            puts("No");            continue;        }        for(int i=2;i<=n-1;i++)            if(mul(ssa[i-1],ssa[i+1])!=mul(ssa[i],ssa[i]))            {                f=0;                break;            }        if(f) puts("Yes");        else puts("No");    }    return 0;}


1004 欧拉函数模板题

如果直接叫我算法欧拉函数我是会的,如果变下形,隐藏得很深,那我就不会了。。。

打表的欧拉函数来一发 复杂度O(n)

#include<iostream>using namespace std;const int maxn=1000005;int phi[maxn];int main(){    int n,t;    for(int i=0;i<maxn;i++) phi[i]=i;    for(int i=2;i<maxn;i+=2) phi[i]/=2;    for(int i=3;i<maxn;i++)        if(phi[i]==i)        {            for(int j=i;j<maxn;j+=i) phi[j]=phi[j]/i*(i-1);        }    cin>>t;    while(t--)    {        cin>>n;        cout<<phi[n+1]<<endl;    }    return 0;}

基于分解质因数的来一发

这两个的区别在于,打表法快是快,但是数组最多开到1000000,而基于分解质因数的可以求10^12以内的所有数的欧拉函数。

#include<cstdio>#include<cstring>#include<iostream>using namespace std;int f(int n){    int ans = n;    for (int i = 2 ; i * i <= n ; i++)    if (n % i == 0)    {        ans = ans / i * (i-1);        while (n%i==0) n/=i;    }    if (n != 1)        ans = ans / n * (n - 1);    return ans;}int main(){    int T;    int n;    cin>>T;    while (T--)    {        cin>>n;        n++;        int ans = f(n);        cout<<ans<<endl;    }    return 0;}

总的来说,这套题比较简单,但是做的不是很理想。


0 0
原创粉丝点击