ACM训练日志4(ICPC沈阳赛网络赛预赛Supreme Number)

   今天打得icpc沈阳赛网络赛预赛,说实话今天的表现有点超出我的预期,因为我们出K题的时候查了一下榜,当时只有两个16级队分别出了一个题。比赛开始后我预览了一遍题目,发现K题题目很短,就快速读懂了题目,并把题告诉了两位队友,题目是比较简单,但是由于数据太大,着实有点打怵,但是北大9分钟AC,我们还是决定试一试。
  其实这个题没有早点出怪我,刚开始把题目理解为了每个数据的每一位保证是素数或者是1,没有读出来子序列(这个单词官方还加粗了!!),后来大饼看了问答中有人问了子序列的问题,我们才意识到子序列没有看出来。就此我们的思路豁然开朗,既然要保证子序列是素数或者1,那么1、2、3、5、7组成的数中就不可能存在两个相同的数字,比如323中存在33不合题意(其实在这个地方有bug,我们wa了几次也是因为这个bug,后面我会再讲)那么问题就简单了,首先我们把这五个数进行了全排列(于衡的活),包括5个数的全排列,4个数的全排列…把全排列的数用素数筛法筛出来其中的素数,再把这些素数中包含有非素数子序列的数筛去,得到的数其实没有几个了,而且这些数就是最终的结果集合了,然后把这些数从小到大排列放到数组里,判断输入的数是在这个数组的哪个区间里,取区间下限 就是结果了。
   大饼敲完代码后我确实特别激动,看到提示说您有测试数据未通过时,心拔凉拔凉的,然后我开始回过头来看刚才筛掉的数,其实有一部分是多筛了,比如131不能筛掉(这就是上面我提到的bug),我最开始想的是一旦有两个相同的数字,肯定是11的倍数,就要筛掉,但是忽略掉了11本身!!改了后最后终于AC,AC的时候真的是特别激动,喜悦难以言表(即使这是人北大9分钟一血的题)。
   回头再看这道题我们走了很多弯路,比如1 2 3 5 7 的全排列根本不用算,因为里面含有2和5,肯定会有子序列25或者52,不合题意,同理几种4个数的全排列其实最终也没有符合题意的。
   这是我今天做题的头脑历程,下面给出题目和AC代码:
   题目(https://nanti.jisuanke.com/t/31452):

A prime number (or a prime) is a natural number greater than 11 that cannot be formed by multiplying two smaller natural numbers.

Now lets define a number NN as the supreme number if and only if each number made up of an non-empty subsequence of all the numeric digits of NN must be either a prime number or 11.

For example, 1717 is a supreme number because 11, 77, 1717 are all prime numbers or 11, and 1919 is not, because 99 is not a prime number.

Now you are given an integer N\ (2 \leq N \leq 10^{100})N (2≤N≤10
100
), could you find the maximal supreme number that does not exceed NN?

Input
In the first line, there is an integer T\ (T \leq 100000)T (T≤100000) indicating the numbers of test cases.

In the following TT lines, there is an integer N\ (2 \leq N \leq 10^{100})N (2≤N≤10
100
).

Output
For each test case print “Case #x: y”, in which xx is the order number of the test case and yy is the answer.

样例输入
2
6
100
样例输出
Case #1: 5
Case #2: 73

AC代码:

#include<bits/stdc++.h>
using namespace std;
int prime[]={1,2,3,5,7,11,13,17,23,31,37,53,71,73,113,131,137,173,311,317};
int main(){
    int n;cin>>n;
    int temp;
    int lenth=0;
    int t=0;
    while(t<n){
        string a;
        cin>>a;
        if(a.length()>3){
            printf("Case #%d: 317\n",t+1);
        }
        else{
            temp=atoi(a.c_str());
            for(int i=19;i>=0;i--){
                if(temp>=prime[i]){
                    printf("Case #%d: %d\n",t+1,prime[i]);
                    break;
                }
            }
        }
        t++;
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/weixin_40630836/article/details/82532940
今日推荐