2015 年 JXNU_ACS 算法组寒假第二次周赛

来源:互联网 发布:a 寻路算法 c 编辑:程序博客网 时间:2024/06/05 15:48

2015 年 JXNU_ACS 算法组寒假第二次周赛

比赛链接:http://acm.hdu.edu.cn/diy/contest_show.php?cid=26246
赛后重挂:http://acm.hdu.edu.cn/diy/contest_show.php?cid=26249

Start Time : 2015-02-01 13:00:00   
End Time : 2015-02-01 17:30:00

终榜:http://acm.hdu.edu.cn/diy/contest_ranklist.php?cid=26246&page=1

这次比赛考查的知识都很基础,甚至还有几道就是C语言基础(比如1006 但只有一个人A了),总体难度不大。
高精度、深搜、广搜的题都是模板题,没有转一丁点儿弯的。
这些东西就不废话了,我想吐槽的是你们的编码风格!!! 为毛我看到1001有人函数名取dfs....
随手Google了一篇博文:http://hustcs.is-programmer.com/posts/16567.html
两点建议吧:
1.函数取名要有一定意义
2.重复的代码最好写成函数形式
通过这次比赛我希望大家要注重基础,当然这里的基础也不仅仅是包括基础知识&基本算法——还有编码风格。
and 这次数据没出什么问题,比赛途中开溜了下~ 当然这得感谢@WX 的测题
【这次做题情况不好的同学也不要灰心~~ 对于新生来说,这才刚开始 你需要做的是投入更多的时间】
-----------------------------现在流行分割线-------------------我也来一条玩玩-----------------------

一、1001.Factorial

题意:题目虽是英文,不过学过E文的都不应该存在障碍。so 略。

考点: 大数乘小数  大数加法
PS :很基础的模板题 新生用C++ 15mins 也1AC了,@WX 用Java更是分分钟过了。

直接上代码,没过的看下面的代码。

参考代码

C++:

<pre name="code" class="cpp">#include<iostream>#include<cstring>#include<string>#include<fstream>//#define cin fin//#define cout fout#define maxn 620using namespace std;//ifstream fin("1001.in");//ofstream fout("1001.out");int F1[maxn],F2[maxn],m,n,t;string ToString(int x[]){    string res="";    int i=maxn-1;    for(;i>0&&!x[i];)i--;    for(;i>=0;i--)res+=x[i]+'0';    return res;}string calc(int x[],int k){    for(int i=1;i<=k;i++){        for(int j=0;j<maxn;j++)            x[j]*=i;        for(int j=0;j<maxn;j++)        {            if(x[j]>9){                x[j+1]+=x[j]/10;                x[j]%=10;            }        }    }    return ToString(x);}string Add(){    for(int i=0;i<maxn;i++){         F1[i]+=F2[i];         if(F1[i]>9){            F1[i+1]+=F1[i]/10;            F1[i]%=10;         }    }   return ToString(F1);}int main(){    cin.sync_with_stdio(false);    cin>>t;    while(t--)    {        memset(F1,0,sizeof(F1));        memset(F2,0,sizeof(F2));        F1[0]=F2[0]=1;        calc(F1,m); calc(F2,n);       cout<<Add()<<endl;    }    return 0;}

Java:
import java.util.*;import java.math.*;import java.io.*;public class Main {    static Scanner cin=new Scanner(new BufferedInputStream(System.in));    public static void main(String args[]){        int n,m,t;        t=cin.nextInt();        while(cin.hasNext()){            n=cin.nextInt();m=cin.nextInt();            System.out.println(fac(n).add(fac(m)));        }    }    static BigInteger fac(int n){        BigInteger ans=BigInteger.ONE;        for(int i=1;i<=n;i++) ans=ans.multiply(BigInteger.valueOf(i));        return ans;    }}

二、1002.Fibonacci

题意:这题就是求斐波那契序列
PS:需要注意的是,要用long long ~~还有需要开一个数组,用"动态规划"
  的思想避免重复计算——看看时限就知道了,250ms

参考代码:

#include<iostream>#define maxn 100#define LL long long#include<fstream>//#define cin fin//#define cout foutusing namespace std;//ifstream fin("1002.in");//ofstream fout("1002.out");LL F[maxn],n,t;struct Node{    LL bit,r;}res[maxn];LL fib(int x){    if(F[x])return F[x];    F[x]=fib(x-2)+fib(x-1);    return F[x];}void init(){     for(int i=1;i<95;i++){     LL temp=fib(i),sum=0,num;     num=temp;     while(temp){        sum++; temp/=2;     }     res[i].bit=sum; res[i].r=num;     }}int main(){    F[1]=F[2]=1;    init();    cin>>t;    while(t--){     cin>>n;     cout<<res[n].bit<<" "<<res[n].r<<endl;    }    return 0;}

三、1003.colors

题意:这题就是求组合数

题解;模板题——DFS之 我在群里传的课件中有求组合的代码,我这里就是把 1 2 3.. 
   换成了颜色而已,其实还是一样。还有数据量不大,500ms的时限也算是宽裕

参考代码;

#include<iostream>#include<cstdio>#include<cstring>#define maxn 100+5#include<string>#include<fstream>//#define cin fin//#define cout foutusing namespace std;//ifstream fin("1003.in");//ofstream fout("1003.out");string foll[maxn];int m,n,f[maxn],res[maxn],bz[maxn];void print(){    for(int i=1;i<n;i++)    cout<<foll[res[i]]<<" ";    cout<<foll[res[n]]<<endl;}void comb(int k){    if(k==n){        print();        return ;    }    for(int i=k;i<=m;i++){        if(!bz[i]&&res[k]<i){            res[k+1]=i;            bz[i]=1;            comb(k+1);            bz[i]=0;        }    }}int main(){    while(cin>>m>>n){        memset(res,0,sizeof(res));        memset(bz,0,sizeof(bz));        for(int i=1;i<=m;i++)cin>>foll[i];        comb(0);    }    return 0;}

四、1004.Tank

题意:给定一个图,求Y到T的最短路径长度,其中R和S均为障碍物。

题解:这题也是由我传在群里一个课件中的例题改遍的。

   题目改简单了,变成一道标标准准的BFS模板题——数据量虽然不大,

   但是你想用DFS跑出来该是不行的——我出的数据都是卡DFS的。像这

   种求一个图中两点间的最短路径一般都是用BFS,如果问是否有路则DFS。

   纯模板,没有挖坑。

参考代码:

#include<iostream>#include<cstring>#include<fstream>#define maxn 10000000//#define cin fin//#define cout fout#define N 11using namespace std;//ifstream fin("tank.in");//ofstream fout("tank.out");int m, n, ex, ey, exdir, nodedir, flag;char ch;struct Node{int x, y, step;bool chess[N][N];}stat[maxn], temp;int dir[4][2] = {{ 1, 0 }, { -1, 0 }, { 0, 1 }, { 0, -1 }};bool check(Node x){for (int i = 0; i <= exdir; i++)for (int j = 0; j<m; j++)for (int k = 0; k<n; k++)if (stat[0].chess[j][k] != temp.chess[j][k])return true;return false;}bool End(Node x){if (x.x == ex&&x.y == ey)return true;return false;}int main(){    int sum=0;    cin.sync_with_stdio(false);while (cin >> m >> n&&(m||n)){            sum++;for (int i = 0; i<m; i++)for (int j = 0; j<n; j++){stat[0].chess[i][j] = true;cin >> ch;if (ch == 'R' || ch == 'S'){stat[0].chess[i][j] = false;}else if (ch == 'Y'){stat[0].x = i; stat[0].y = j;stat[0].chess[i][j] = false;}else if (ch == 'T'){ex = i; ey = j;}}stat[0].step = 0;exdir = nodedir = 0; flag = 1;while (nodedir <= exdir&&exdir<maxn&&flag){for (int i = 0; i<4; i++){temp = stat[nodedir];int dx = dir[i][0] + temp.x, dy = dir[i][1] + temp.y;if (dx >= 0 && dx<m&&dy >= 0 && dy<n&&temp.chess[dx][dy]){temp.x = dx; temp.y = dy;temp.chess[dx][dy] = false;temp.step++;if (End(temp)){cout << temp.step << endl;flag = 0;break;}if (check(temp)){//cout << dx << " " << dy << endl;stat[++exdir] = temp;}}}nodedir++;}}return 0;}
五、1005.Tank

题意:略。

题解:根据计算规则——利用"高斯公式"就可以推出来公式了。不过long long 

   型还是必须的——看了下一些WA的代码,达到了我预期的效果。不少同学

   以为只要把存放结果的变量定义为long long就可以,其实如果两个int型

   变量相乘,如果结果超过了int型,那么返回的结果也会是错的。
知道了这点,然后就是几行代码的事了

参考代码:

#include<iostream>#include<fstream>#include<cstdio>#define LL double//#define cin fin//#define cout foutusing namespace std;//ofstream fout("1007.out");//ifstream fin("1007.in");LL m,n,t,sum;int main(){  // freopen("1007.out", "w", stdout);    cin>>t;    while(t--){        cin>>n>>m;         cout<<((m-n)*45+(n+m-1)*(m-n)*5+m)<<endl;    }   return 0;}

【呜呜,打脸了... 如果m=0 n为int型最大,结果还是会超long long~~ 】

六、1006、好大的数

题意:这个题目名,很负责人的告诉大家,我是故意的.... (逃...

题解:这个看着像是大数,其实用double型就可以了——说过要考C语言基础的
   利用pow函数 开方表示成 1/n就可以了 pow(p,1/n);另外要注意的是精度

   问题,不能将结果强转成int。这里提供两种解决方法:
1.用printf控制小数位输出。
2.直接用C++中的cout

参考代码:

#include <iostream>#include<cstdio>#include <math.h>using namespace std;int main(){   // freopen("1005.in", "r", stdin);    //freopen("1005.out", "w", stdout);    double n, p;    while (scanf("%lf %lf", &n, &p) !=EOF)    {        printf("%0.0lf\n", pow(p, 1/n));    }    return 0;}

七、1007.YouKnow

题意:前面一堆废话(介绍UNO)的——我就是故意的~_~ 因为,我也被酱紫坑过,这种情况是会出现的【具体参考2014年ACM-ICPC西安邀请赛&考2014年ACM-ICPC西安现场赛 第一题!!!你们不用自己找,我给链接:http://codeforces.com/gym/100548/attachments
这题的题意就是叫你找规律,难点也在于在规律。
S(1)=0,
S(2)=10,
S(3)=1110,
...
规律就是——S(n)是对S(n-1)的一个描述。
例如求S(2),因为S(1)是一个0 ,所以S(2)=10
然后S(3),因为S(2)=10,是一个1和一个0,
所以S(3)=1110
就酱紫~~
接下来就是构造了

参考代码:

#include<iostream>#include<fstream>#include<string>#define maxn 51using namespace std;//ifstream fin("1007.in");//ofstream fout("1007.out");string F[maxn];//#define cin fin//#define cout foutint n;void calc(int x){    string temp=F[x-1],res="";    int len=temp.size(),num=1;    char ch=temp[0];    for(int i=1;i<len;i++){        if(ch!=temp[i]){            res+=num+'0';            res+=ch;            num=1;            ch=temp[i];        }        else num++;    }    res+=num+'0';    res+=ch;    F[x]=res;}int main(){    F[1]="0";    for(int i=2;i<maxn;i++){        F[i]="";        calc(i);    }   while(cin>>n&&n)        cout<<F[n]<<endl;    return 0;}

八、1008.又是汉诺塔

题解: 绝对值排序+贪心
    在第一次新生训练赛的时候出了一道绝对值排序的题,这里稍微改了下。
    这里就是每次找出最小的数,贪心的思想,具体看代码即可。

参考代码:

#include<iostream>#include<fstream>#include<algorithm>#define LL long long#define maxn 100+5//#define cin fin//#define cout foutusing namespace std;//ifstream fin("1008.in");//ofstream fout("1008.out");LL num[maxn],t,n,sum;LL F(LL x){    if(x<0)return -x;    return x;}bool cmp(LL x,LL y){    return F(x)<F(y);}int main(){    cin.sync_with_stdio(false);    while(cin>>n){        sum=0;        for(int i=0;i<n;i++) cin>>num[i];        sort(num,num+n,cmp);        LL temp=num[0]; sum=1;        for(int i=1;i<n;i++){            if(temp*num[i]<0){                temp=num[i];                sum++;            }        }        cout<<sum<<endl;    }    return 0;}
【转载请注明出处】
作者:MummyDing
原文链接:http://blog.csdn.net/mummyding/article/details/43372905




0 0
原创粉丝点击