bestcoder round 75

King's Cake

 
 Accepts: 960
 
 Submissions: 1572
 Time Limit: 2000/1000 MS (Java/Others)
 
 Memory Limit: 65536/65536 K (Java/Others)
问题描述
阅兵式前一天,是国王的生日,大臣们为他准备了一个 n \times m(1\le n, m \le 10000)n×m(1n,m10000) 的蛋糕。他准备切蛋糕,但他切蛋糕有奇奇怪怪的癖好,他每次只切一刀,切下一个正方形蛋糕。请问它最多能切出多少个正方形蛋糕?
输入描述
第一行一个整数表示测试组数:T(0 < T\le1000)T(0<T1000) 。

每组数据占一行,每行两个整数 n \times m(1\le n, m \le 10000)n×m(1n,m10000),表示蛋糕的大小。
输出描述
TT 行,每行一个整数表示最多能切出的正方形蛋糕数量。
输入样例
2
2 3
2 5
输出样例
3
4
Hint
对于第一组数据,可切出一个 2\times22×2, 两个 1\times 11×1,共 33 个。

对于第一组数据,可切出两个 2\times22×2, 两个 1\times 11×1,共 44 个。
第一题,直接模拟即可,起先没怎么看懂题意就打代码,浪费了一些时间。
#include<cstdio>
#include<iostream>
using namespace std;
int t,n,m,ans;
int main()
{
    cin>>t;
    while(t--)
    {
        ans=0;
        scanf("%d%d",&n,&m);
        while(n!=0&&m!=0)
        {
            int x=min(n,m);
            int y=max(n,m);
            ans=ans+1;
            if(x==n) m=m-x;else n=n-x;
        }
        cout<<ans<<endl;
    }
    return 0;
}

King's Phone

 
 Accepts: 310
 
 Submissions: 2980
 Time Limit: 2000/1000 MS (Java/Others)
 
 Memory Limit: 65536/65536 K (Java/Others)
问题描述
阅兵式上,国王见到了很多新奇东西,包括一台安卓手机。他很快对手机的图形解锁产生了兴趣。

解锁界面是一个 3 \times 33×3 的正方形点阵,第一行的三个点标号 1, 2, 31,2,3,第二行的三个点标号 4, 5, 64,5,6,第三行的三个点标号 7, 8, 97,8,9。密码本身是一段序列,表示经过点的先后顺序,但遵循如下规则:

1. 密码至少经过四个点。

2. 不能重复经过同一个点。

3. 路径上的中间点不能跳过,除非已经被经过(34273427 是合法的,但 37243724 不合法)。

他想设置的密码的长度为正整数 k(1\le k\le 9)k(1k9),密码序列为 s_1 s_2...s_k(0\le s_i < INT\_MAX)s1s2...sk(0si<INT_MAX),他想知道这个密码序列是否合法,这个问题交给了你。
输入描述
第一行一个整数表示测试组数:T(0 < T\le100000)T(0<T100000) 。

每组数据占一行,每行第一个数 kk,设置密码的长度;接着 kk 个正整数,之间用空格隔开,表示密码序列 s_1s_2...s_ks1s2...sk
输出描述
TT 行。对每组数据,若合法输出 `valid`,否则输出 `invalid`。
输入样例
3
4 1 3 6 2
4 6 2 1 3
4 8 1 6 7
输出样例
invalid
valid
valid
Hint
对于第一组数据,1133 跳过了路径上的点 22,所以不合法。

对于第二组数据,1133 时点 22 已经被经过了,所以合法。

对于第三组数据,8\rightarrow 1 \rightarrow 6 \rightarrow 78167 路径均没有中间点,所以合法。
第二题也是纯模拟,理解好题意即可。坑爹的是密码序列里会有0和大于9的数,需要特判。。。(论比赛时关注讨论版的重要性)
#include<cstdio>
#include<iostream>
using namespace std;
int f[15][15],h[15];
int t,n;
int a[15];
int main()
{
    f[1][3]=2;f[1][7]=4;f[1][9]=5;
    f[2][8]=5;
    f[3][7]=5;f[3][9]=6;
    f[4][6]=5;
    f[7][9]=8;
    for(int i=1;i<=9;i++)
    for(int j=1;j<=9;j++)
    if(i>j) f[i][j]=f[j][i];
    cin>>t;
    while(t--)
    {
        scanf("%d",&n);
        for(int i=1;i<=n;i++) scanf("%d",&a[i]);
        int p=0;
        if(n<4) p=1;
        for(int i=1;i<=9;i++) h[i]=0;
        for(int i=1;i<=n;i++)
        {
            if(a[i]>9||a[i]==0) 
            {
                p=1;
                break;
            }
            if(i<n)
            {
                int mid=f[a[i]][a[i+1]];
                if(mid>0) if(h[mid]==0) p=1;
            }
            if(h[a[i]]==1) p=1;
            else h[a[i]]=1;
        }
        if(p==1) printf("invalid\n");
        else printf("valid\n");

    }
    return 0;
}

King's Order

 
 Accepts: 381
 
 Submissions: 1361
 Time Limit: 2000/1000 MS (Java/Others)
 
 Memory Limit: 65536/65536 K (Java/Others)
问题描述
国王演讲后士气大增,但此时战争还没有结束,国王时不时要下发命令。

由于国王的口吃并没有治愈,所以传令中可能出现:“让第三军-军-军,到前线去” 这样的命令。由于大洋国在军队中安插了间谍 , 战事紧急,很多时候前线的指挥官不能分清哪些命令真正来自国王。但国王的命令有一个特点,他每次连续重复的字符最多 33 次. 所以说他的命令中没有:“让第三军-军-军-军 , 到前线去”,但是可以有 :“让第三军-军 , 到前线去” 。

此时将军找到了你,你需要告诉他,给定命令的长度长度为 nn,有多少种不同的命令可以是国王发出的 。(也就是求长度为 nn 的合格字符串的个数)当然,国王可能说出一句话没有犯任何口吃,就像他那次演讲一样。

为了简化答案,国王的命令中只含有小写英文字母,且对答案输出模 10000000071000000007。

我们认为两个命令如果完全相同那么这两个字符串逐个比较就完全相同。
输入描述
第一行一个整数表示测试组数:T(T \le10)T(T10)。

每组数据占一行,每行一个正整数 n(n \le 2000)n(n2000) 表示字符串的长度。
输出描述
TT 行,每行一个整数表示合法的命令数量。
输入样例
2
2
4
输出样例
676
456950
Hint
两个中没有不符合要求的,所以答案为 26\times 26 = 67626×26=676

四个不符合要求的只有 `aaaa` `bbbb` ... `zzzz`总共 26 个

那么答案就是: 26^4-26 = 45695026426=456950
第三题,我直接把回溯改成记忆化,拒绝高深数位dp
#include<cstdio>
#include<iostream>
#include<cstring>
using namespace std;
const int m=1000000007;
int n,t;
int f[2005][27][4];
int dfs(int k,int le,int ci)
{
    if(f[k][le][ci]!=-1) return f[k][le][ci];
    if(k==n) return 1;
    int s=0;
    for(int i=1;i<=26;i++)
    if(le==i)
    {
        if(ci==3) continue; else s=(s+dfs(k+1,i,ci+1))%m;
    }
    else s=(s+dfs(k+1,i,1))%m;
    return f[k][le][ci]=s;
}
int main()
{
    cin>>t;
    while(t--)
    {
        memset(f,-1,sizeof(f));
        cin>>n;
        cout<<dfs(0,0,0)<<endl;
    }
    return 0;
}
第四题的话,表都打好了,结果事后才知道代码有行数限制,我打表的话都换行了,结果想再打一个,已经没时间了。。。看来还是打表经验不够丰富啊。。。

你可能感兴趣的:(bestcoder round 75)