华东交通大学2018年ACM“双基”程序设计竞赛

华东交通大学2018年ACM“双基”程序设计竞赛

1. A.ecjtuacm

题目描述
为了给acm打劲,我们喊出"ecjtu"后,你要喊出"ecjtuacm"。

输入描述:
一行字符串"ecjtu"。
输出描述:
在一行中输出"ecjtuacm"(要换行)。
示例1
输入
ecjtu
输出
ecjtuacm
题目没什么讲的

#include<bits/stdc++.h>
using namespace std;

int main()
{
    string a;
    cin >> a;
    cout << "ecjtuacm" << endl;
    return 0;
}

2. B.公式题(1)

链接:https://ac.nowcoder.com/acm/contest/221/B
来源:牛客网

题目描述
令f(n)=2f(n-1)+3f(n-2)+n,f(1)=1,f[2]=2。
告诉你n,输出f(n)的结果,结果对1e9+7取模。
输入描述:
多组输入,每行一个整数n(1<=n<=1000),如果输入为0,停止程序。
输出描述:
输出对应g(n)的值,结果对1e9+7取模。
示例1
输入
1
5
9
456
0
输出
1
95
7789
734891569

矩阵快速幂模板题,(听说打表也能过)

#include <bits/stdc++.h>
#define ll long long
using namespace std;
const int mod = 1e9 + 7;
const int N = 10;
int n;
struct node{
    ll m[N][N];
    node(){
        memset(m, 0, sizeof(m));
    }
};
 
node operator * (node a, node b)
{
    node c;
    for(int i = 0; i < 5; i++){
        for(int j = 0; j < 5; j++){
            for(int k = 0; k < 5; k++){
                c.m[i][j] += a.m[i][k] * b.m[k][j];
                c.m[i][j] %= mod;
            }
        }
    }
    return c;
}
 
node pow(node a, ll k)
{
    node b;
    for(int i = 0; i < 5; i++){
        b.m[i][i] = 1;
    }
    while(k){
        if(k&1) b = b * a;
        a = a * a;
        k >>= 1;
    }
    return b;
}
 
int main()
{
    while(~scanf("%d", &n) && n){
        if(n == 1){
            cout << 1 << endl;
            continue;
        }else if(n == 2){
            cout << 2 << endl;
            continue;
        }else if(n == 3){
            cout << 10 << endl;
            continue;
        }
        node a;
        a.m[0][0] = 2;
        a.m[0][1] = 3;
        a.m[0][3] = 1;
        a.m[1][0] = 1;
        a.m[2][1] = 1;
        a.m[3][3] = 1;
        a.m[3][4] = 1;
        a.m[4][4] = 1;
        node b = pow(a, n-3);
        ll ans = 0;
        ans = (b.m[0][0] * 10 + b.m[0][1] * 2 + b.m[0][2] + b.m[0][3] * 4 + b.m[0][4]) % mod;
        printf("%lld\n", ans);
    }  
    return 0;
}

3. C.公式题(2)

链接:https://ac.nowcoder.com/acm/contest/221/C
来源:牛客网

题目描述
令f(n)=2f(n-1)+3f(n-2)+n,f(1)=1,f(2)=2
令g(n)=g(n-1)+f(n)+n*n,g(1)=2
告诉你n,输出g(n)的结果,结果对1e9+7取模

输入描述:
多组输入,每行一个整数n(1<=n<=1e9),如果输入为0,停止程序。
输出描述:
在一行中输出对应g(n)的值,结果对1e9+7取模。
示例1
输入
1
5
9
456
0
输出
2
193
11956
634021561

同上题,构造矩阵时要把f(n)考虑进去。

//提交时间:2018-11-17 15:28:28 语言:C++ 代码长度:1703 运行时间: 80 ms 占用内存:352K 
#include <bits/stdc++.h>
#define ll long long
using namespace std;
const int mod = 1e9 + 7;
const int N = 10;
int n;
struct node{
    ll m[N][N];
    node(){
        memset(m, 0, sizeof(m));
    }
};
 
node operator * (node a, node b)
{
    node c;
    for(int i = 0; i < 8; i++){
        for(int j = 0; j < 8; j++){
            for(int k = 0; k < 8; k++){
                c.m[i][j] += a.m[i][k] * b.m[k][j];
                c.m[i][j] %= mod;
            }
        }
    }
    return c;
}
 
node pow(node a, ll k)
{
    node b;
    for(int i = 0; i < 8; i++){
        b.m[i][i] = 1;
    }
    while(k){
        if(k&1) b = b * a;
        a = a * a;
        k >>= 1;
    }
    return b;
}
 
int main()
{
    while(~scanf("%d", &n) && n){
        if(n == 1){
            cout << 2 << endl;
            continue;
        }else if(n == 2){
            cout << 8 << endl;
            continue;
        }else if(n == 3){
            cout << 27 << endl;
            continue;
        }
        node a;
        a.m[0][0] = 1;
        a.m[0][2] = 1;
        a.m[0][5] = 1;
        a.m[1][0] = 1;
        a.m[2][2] = 1;
        a.m[2][3] = 2;
        a.m[2][4] = 1;
        a.m[3][3] = 1;
        a.m[3][4] = 1;
        a.m[4][4] = 1;
        a.m[5][3] = 1;
        a.m[5][4] = 1;
        a.m[5][5] = 2;
        a.m[5][6] = 3;
        a.m[6][3] = 1;
        a.m[6][6] = 2;
        a.m[6][7] = 3;
        a.m[7][6] = 1;
        node b = pow(a, n - 2);
        ll ans = 0;
        ans = (b.m[0][0] * 8 + b.m[0][1] * 2 + b.m[0][2] * 9 + b.m[0][3] * 3 + b.m[0][4] * 1 + b.m[0][5] * 10 + b.m[0][6] * 2 + b.m[0][7])  % mod;
        printf("%lld\n", ans);
    }  
    return 0;
}

4. D.俺は人间をやめるぞ!

链接:https://ac.nowcoder.com/acm/contest/221/D
来源:牛客网

题目描述
摸鱼之王MIKU酱想去埃及玩,需要一个人陪同。小新和小磊都想陪MIKU酱一起去,但名额只有一个。所以小磊和小新决定用一个小游戏来决定谁和MIKU酱出去玩。
游戏的道具是21张塔罗牌,塔罗牌分为大牌和小牌,其中大牌有22张,分别是编号为0的愚者(The Fool)和编号为21的世界(The World)。
给出22张的塔罗牌以及其编号如下:
【0】愚者(The Fool,0)
【1】魔术师(The Magician,I)
【2】女祭司(The High Priestess,II)
【3】皇后(The Empress,III)
【4】皇帝(The Emperor,IV)
【5】教皇(The Hierophant,or the Pope,V)
【6】恋人(The Lovers,VI)
【7】战车(The Chariot,VII)
【8】力量(Strength,VIII)
【9】隐士(The Hermit,IX)
【10】命运之轮(The Wheel of Fate,X)
【11】正义(Justice,XI)
【12】倒吊人(The Hanged Man,XII)
【13】死神(Death,XIII)
【14】节欲(Temperance,XIV)
【15】恶鬼(The Devil ,XV)
【16】塔(The Tower,XVI)
【17】星辰(The Star,XVII)
【18】月亮(The Moon,XVIII)
【19】太阳(The Sun,XIX)
【20】审判(Judgement,XX)
【21】世界(The World,XXI)
游戏的规则是:将22张塔罗牌打乱,然后分别从中翻开一张卡,两张卡的权值和如果为正数,则小新获胜,如果为负数,则小磊获胜。如果这张卡是正位(即是正向的),那么这张牌的权值就为他的序号,如果是逆位(反向),则权值就为序号的相反数。例如:正位的世界的权值为21,逆位的死神的权值为 -13。因为愚者的正逆位都是0,为了让游戏更有趣,他们附加了一条规则:如果翻出了正位的愚者,那么直接判定小新获胜,如果出现了逆位的愚者,那么小磊获胜。
大家都不知道,小磊其实具有将时间暂停几十秒的能力。但是小磊并不想用这个能力作弊,他只想在小新翻开牌的瞬间看看他翻到的是什么牌,然后计算自己可能获胜的几率。
输入描述:
多组输入,输入一个数字a(0<=a<=21)和一个数字b(0<=b<=1),a代表小新翻出来的牌的序号,b代表小新翻出卡的位序,b为0则为逆位,为1则为正位,如果输入为"-1 -1",终止输入。
输出描述:
输出格式为:a/b 该分式为最简式。中间的杠为字符“/”。如果结果为0,则输出“owatta”。如果已经获胜(小新的牌为逆位愚者)则输出“1”。
示例1
输入
0 1
输出
owatta

水题,模拟一下就行。

//提交时间:2018-11-17 17:02:07 语言:C++ 代码长度:721 运行时间: 4 ms 占用内存:364K
#include <bits/stdc++.h>
#define ll long long
using namespace std;
const int mod = 1e9 + 7;
const int N = 10;
 
int a, b;
int gcd(int m, int n){
    return m == 0 ? n : gcd(n % m, m);
}
int main()
{
    while(cin >> a >> b){
        if(a == -1 && b == -1)
            break;
        if(a == 0){
            if(b == 0){
                cout << 1 << endl;
            }else{
                cout << "owatta" << endl;
            }
        }else{
            int ans;
            if(b == 1){
                ans = 1 + 20 + (a - 1);
            }else{
                ans = 1 + (21 - a);
            }
            printf("%d/%d\n",(42 / gcd(ans, 42)) - (ans / gcd(ans, 42)), 42 / gcd(ans, 42));
        }
    }
    return 0;
}

7. G.7的意志

链接:https://ac.nowcoder.com/acm/contest/221/G
来源:牛客网

题目描述
定义一个序列a:7,77,777…,7777777(数字全为7的正整数,且长度可以无限大)
clearlove7需要从含有7的意志的数里获得力量,如果一个整数能被序列a中的任意一个数字整除,并且其数位之和为序列a中任意一个数字的倍数,那么这个数字就含有7的意志,现在给你一个范围[n,m],问这个范围里有多少个数字含有7的意志。

输入描述:
多组输入,每行两个个整数n,m(1<=n<=m<=1e18),如果输入为"0 0",停止程序。
输出描述:
每一行输出含有7的意志的数的个数。
示例1
输入
1 7
1 100
1 1000
0 0
输出
1
3
21
说明
1到100中符合条件的数字为7,70,77
数位dp,题目就是求一段范围内是7的倍数,且数位之和为7的倍数,的数的个数。

	#include <bits/stdc++.h> 
using namespace std;
#define ll long long
const int N = 20;
const int mod = 1e9 + 7;

ll a[N];
ll dp[N][10][10];
ll n, m;
// dp[pos][pre][sum]
// pos------------------数位
// pre------------------数的余数
// sum------------------数位和的余数
ll dfs(int pos, int pre, int sum, bool limit)
{
    if(pos == -1)
        return (sum % 7 == 0 && pre % 7 == 0);
    if(!limit && dp[pos][pre][sum] != -1)
        return dp[pos][pre][sum];
    int up = limit ? a[pos] : 9;
    ll ans = 0;
    for(int i = 0; i <= up; i++){
        ans += dfs(pos - 1, (pre * 10 + i) % 7, (sum + i) % 7, limit && i == a[pos]);
    }
    if(!limit && dp[pos][pre][sum] == -1){          //记忆化搜索中的“记忆化”过程
        dp[pos][pre][sum] = ans;
    }
    return ans;
}


ll solve(ll x)
{
    int len = 0;
    while(x){
        a[len++] = x % 10;
        x /= 10;
    }
    return dfs(len - 1, 0, 0, 1);
}

int main()
{
    memset(dp, -1, sizeof(dp));
    while(cin >> n >> m){
        if (n == 0 && m == 0)
            break;
        printf("%lld\n", solve(m) - solve(n - 1));
    }
    return 0;
}

10. J.死肥宅的冲分计划

链接:https://ac.nowcoder.com/acm/contest/221/J
来源:牛客网

题目描述
国庆十天假,死肥宅选择回家休息,休息期间死肥宅开始了他的召唤师峡谷冲分之旅,冲分之前死肥宅向其他队员打赌十天内必上王者,已知死肥宅初始段位为黄金,因为死肥宅是游戏鬼才,所以他可以控制每天的段位变化不会超过一个大段,每天都会有队员查看下死肥宅的段位,如果死肥宅上了一个大段那么就会在小本本上记一个1,如果大的段位没有变化那么就会在小本本上记一个0,如果掉了一个大段,那么就记一个7,但是存在一些特殊情况使得队员记录的数字代表的意义会发生一些改变(详情可看备注)十天后,我们可以得到一个10个数字的序列,试着根据这串序列算出死肥宅是否上了王者,如果死肥宅成功的话那么请输出“666”,否则请输出“777"。

输入描述:
多组输入,每行输入10个数字,只包含1,0,7,三个数字。
输出描述:
10天后如果死肥宅的段位达到王者,输出"666";否则输出"777"。
示例1
输入
7 7 7 7 7 7 7 7 7 7
1 1 1 1 1 1 1 1 1 1
输出
777
666

备注:
段位晋级规则为:
黄铜 -> 白银 -> 黄金 -> 白金 -> 钻石 -> 大师 -> 王者
特殊状况:
如果降到黄铜,且下一天仍然没有升段,因为黄铜下面没有其他段位,那么记录信息的队员会在7和0中随机记录一个,7和0都代表当前段位没有发生变化。
如果升到王者,且下一天仍然没有掉段,因为王者之上没有其他段位,那么记录信息的队员会在0和1中随机记录一个,1和0都代表当前段位没有发生变化。
水题,模拟,(注意起始为黄金)。

#include <bits/stdc++.h>
#define ll long long
using namespace std;
const int mod = 1e9 + 7;
const int N = 10;
 
int a[10];
 
int main()
{
    while(~scanf("%d", &a[0])){
        for (int i = 1; i < 10; i++){
            scanf("%d", &a[i]);
        }
        int ans = 2;
        for (int i = 0; i < 10; i++){
            if(a[i] == 0){
            }else if(a[i] == 1){
                if(ans != 6){
                    ans++;
                }
            }else{
                if(ans != 0){
                    ans--;
                }
            }
        }
        if (ans == 6){
            cout << 666 << endl;
        }else{
            cout << 777 << endl;
        }
    }
    return 0;
}
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值