新生排位赛第三场 快速幂 hash散列

第四题运用了快速幂的知识

第五题运用了hash散列的知识

第一题

虽然是一道签到题,但是注意格式输出问题,后面不要多加空格

不过我到现在还没弄明白七段管是怎么回事

学长有更简洁的方法

我的太多case代码太长


时间限制 1000 ms  内存限制 65536 KB

题目描述

学姐的七段数码管玩的出神入化。 现在给你一个浮点数,你需要把它以七段数码管的形式输出出来。 一个(2n+1)n的矩阵来表示七段数码管,若下标均从0开始,则以第0列的两个,第n1列的两个,第0行的一个,第n行的一个,第2n行的一个表示七个段。小数点所占矩形为(2n+1)1,点在中间最下面一列。每一个数字或小数点矩阵用一列空格隔开。 数码管亮的部分用#覆盖,其余部分用空格补全,若一个数字或小数点的行末尾无#,也要用空格字符补全为(2n+1)n 细节参见样例。

输入格式

输入有多组数据,数据不超过100组,每组数据给一个整数n(3n10),和一个浮点数,输入保证每一个浮点数的总长度为4位且没有前导0。

输出格式

输出他的数码管显示。每组数据末尾输出一个空行。

输入样例

3 2330
3 1456
4 78.9

输出样例

### ### ### ###
  #   #   # # #
  #   #   # # #
### ### ### # #
#     #   # # #
#     #   # # #
### ### ### ###

  # # # ### ###
  # # # #   #  
  # # # #   #  
  # ### ### ###
  #   #   # # #
  #   #   # # #
  #   # ### ###

#### ####   ####
   # #  #   #  #
   # #  #   #  #
   # #  #   #  #
   # ####   ####
   # #  #      #
   # #  #      #
   # #  #      #
   # #### # ####
#include 
#include 
#include 
#include 
#include 
#include 
#include 
using namespace std;
char a[25][50];//数组大小也要开得合适

int main()
{
    int n, m;
    int first, last;
    char b[5];
    while(~scanf("%d %s", &n, b))
    {
        //itoa(m, b, 10);这个地方多余担心了,char非常好用,根本不需要用到itoa
        memset(a, ' ', sizeof a);//初始化所有都为空格,memset是一个字节一个字节初始化的,它在string.h头文件里,针对的就是字符的初始化
        last = -1;
        for (int i=0; i<4; i++)
        {
            if (b[i] == '.')//如果是小数点单独列出
            {
                a[2*n][last+1] = '#';//先给区域内都预先打上‘#’
                last += 2;
                continue;
            }


            for (int k=0; k<(2*n+1); k++)
                for (int j=last+1; j



第二题 本题可能有点坑的是方向问题,我画了半天转了好几个圈,才弄明白顺时针转指定角度就行,注意给的数对90取商后,还要对4取余


时间限制 1000 ms  内存限制 65536 KB

题目描述

学姐在学图形学,然后写了一个能让图片逆时针转圈的程序。这个程序很厉害,只要输入灰度图片和旋转过的角度(90的倍数),就可以输出一个新图片。给你一张图片的灰度矩阵,和它已转过的角度,请输出图片旋转前的灰度图矩阵。

输入格式

接下来给出图片扫描稿的高H和宽W,图片的灰度矩阵,高宽都小于500,题目其他的所有数值都小于int的范围。多组数据,组数小于20,EOF结束。

输出格式

一个矩阵

输入样例

2 2 180
0 1
1 2

输出样例

2 1
1 0























/*
USER_ID: test#zsp
PROBLEM: 430
SUBMISSION_TIME: 2014-07-18 14:40:11
*/
#include 
#include 
#include 
#include 
#include 
#include 
#include 
using namespace std;
int a[505][505];
int b[505][505];
int main()
{
    int h, w, rod;
    while (~scanf("%d %d %d", &h, &w, &rod))
    {
        memset(a, 0, sizeof a);
        for (int i=0; i



第三题 hash散列

关于hash 散列,我们要选好三个数字,

第一个是散列值,本题选取了 long long 的最大值,差不多是,10的18次方以上,因为两个long long 爆掉以后会自动取模,所以直接就不用写了,相当于我们把每个字符散列在long long的最大值这么大的范围上


而另外一个是将字符串转变成数字时用的b,这个数字的选取大了不好小了也不好,我做了好几组数据(包括10000007,19,29)的检测,最后发现对于本题的数据271是时间最短的.

后来又仔细一看,发现我错了,其实没多少差别,这种东西如果结果相差不大,就没必要纠结了,一摸一样的代码多交几遍时间也会不同


第三个数字是构建vector数组的大小,将模后的值储存在一个不大不小空间的vector向量数组里,太大了白白占用空间,太小了每条链拉得太长也不好,本题选取的是100007;没有做后续数据检测别的是否更好


还有一个相当惊人的发现,在上一场的总结报告中曾经提过string和string.h的头文件是不一样的,事实上string是c++独有的string类的头文件,而string.h其实相当于cstring

,(其包括memset函数)其实是c的函数的头文件,在本题中如果多加一个string(c++)头文件竟然会慢几十毫秒.(其实可能相差不大,可能和主机本身也有关系,我多虑了)



408. 字符串

时间限制2000 ms 内存限制512000 KB

题目描述

维护一个字符串集合:初始为空,依次处理一些插入操作,并在插入之后输出该字符串在集合中出现的次数。

字符串的长度不超过100,字符串个数不超过100000。

输入格式

输入文件包含若干行,每行为一个字符串,依次代表一个待插入的字
符串。该字符串一定非空,且仅包含英文字母和数字。

输出格式

对于每个插入操作输出一行一个整数,代表插入该字符串之后,该字
符串在集合中出现的次数。

输入样例

str1
str2
str1
str1
str2
str3

输出样例

1
1
2
3
2
1




#include 
#include 
#include 
//#include //这个加上后竟然会时间增加几十秒
#include 
#include 
#include 
#include 
#include 
#define maxn 100007

using namespace std;

typedef unsigned long long ull;
vector  a[100008];

int main()
{
    int t;
    char sl[105];
    //string
    ull temp = 0;
    for (int i=0; i<100008; i++)
        a[i].clear();
    while(~scanf("%s", sl))
    {
        temp = 0;
        //int len = sizeof sl;
        int len = strlen(sl);
        for (int i=0; i




第四题 快速幂

题目规律非常好找,4的(n-1)次方,但是我一开始想开个10的九次方大的数组预先储存每个n对应的ans,不过显然时间大大超乎我的预料,估计得一分多钟才能跑一遍,后来我去掉几个零还要几秒。不过显然是因为我不知道快速幂这个东西。于是我想这么大,难不成是对1000000007的模,循环有规律,于是用文件输出,学习上次学长教的用写字板找规律,竟然随便选了几个数用查找功能还告诉我没重复的,所以白忙活了半天

这里再推荐一下怎么用文件输出结果

#include //加一个头文件,当然还要别的头文件
using namespace std;

int main()
{
    ofstream outfile("b.txt");//这里要注意如果分开写要改成下面加个“.open”
    /*ofstream outfile;
    outfile.open("b.txt");*/
    for (int i=0; i<100; i++)
        outfile << i << " ";
    outfile.close();

    return 0;
}



时间限制 1000 ms  内存限制 65536 KB

题目描述

田田申请了一个新的oj账号,打算取一个霸气而简单的名字。 什么叫简单呢?说白了田田脑子不好使,只能记住abcd这4个字母组成单词。 怎么叫霸气呢?田田认为a个个数一定要有奇数个,b的个数一定要有偶数个(包括0)才可以。 现在田田取了一个长为n的账号,但是由于田田的记性实在太差了,而把账号忘记了. 于是把这个问题交给了聪明的wzt,而他认为这道题太过于简单就把这道题交给了你 究竟这个账号有多少种可能?你只需得到这个结果模109+7的值

输入格式

多组case,第一行为case数T,之后T行每行一个整数n。 1n109T100

输出格式

一个case对应一行输出

输入样例

2
1
2

输出样例

1
4
先贴不是快速幂的代码


/*
USER_ID: test#zsp
PROBLEM: 428
SUBMISSION_TIME: 2014-07-18 16:46:42
*/
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#define maxn 1000000007
using namespace std;
int a[100005];
long long cal(int n)
{
    if (n<=100000)
        return a[n];
    else
        return cal(n/2)*cal(n/2)%maxn*a[n-(n/2)*2]%maxn;
}
int main()
{
    a[0] = 1;
    a[1] = 4;
    for (int i=2; i<=100000; i++)
    {
        a[i] = (long long)a[i-1]*4%maxn;
    }
 
    int T;
    scanf("%d", &T);
    while (T--)
    {
        int m;
        scanf("%d", &m);
        int ans = cal(m-1);
        printf("%d\n", ans);
    }
    return 0;
 
}

再来研究一下快速幂

快速幂模板

//下面是 m^n  % k 的快速幂:
// m^n % k
int quickpow(int m,int n,int k)
{
    int b = 1;
    while (n > 0)
    {
          if (n & 1)//按位与运算,可以判断n的奇偶性,也可以判断n的二进制最后一位是1还是0(当然这两个本质是一样的)
             b = (b*m)%k;
          //显然如果n的二进制末尾是1就要归入计算,末尾不是0就不计算
          n = n >> 1 ;
          m = (m*m)%k;
    }
    return b;
} 

当然不能照抄啦,我们题目的这个数据比较大要强制类型转换一下,不然会爆,而且Int爆了估计就变0了,long long 爆了会自动取long long 最大级别的模


#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#define maxn 1000000007
using namespace std;

int quickpow(int m,int n,int k)
{
    int b = 1;
    while (n > 0)
    {
          if (n & 1)//按位与运算,可以判断n的奇偶性,也可以判断n的二进制最后一位是1还是0(当然这两个本质是一样的)
             b = ((long long)b*m)%k;
          //显然如果n的二进制末尾是1就要归入计算,末尾不是0就不计算
          n = n >> 1 ;
          m = ((long long)m*m)%k;
    }
    return b;
}

int main()
{
    int T;
    scanf("%d", &T);
    while (T--)
    {
        int m;
        scanf("%d", &m);
        //int ans = cal(m-1);
        printf("%d\n", quickpow(4, m-1, maxn));
    }
    return 0;

}

实验数据证明快速幂的时间比我自己那个快多了,初步验证了一下,快速幂9秒(针对此题)我的预处理了一个a[100005]的数组要32毫秒,如果没有预处理,自己试运行了一下求一个10的9次方就好几秒,模板果然好啊


快速幂模板链接(包括还有矩阵的)



第五题




你可能感兴趣的:(新生排位赛)