180308 思路反思

重要的是思考的过程而不是AC

看大白书集思广益,竞赛题真的是很玄妙的东西

Problem: 括号串

Time limit: 1s Mem limit: 128 MB AC/Submission: 37/92 Discuss (0)

Problem Description

给出一个仅由’(‘,’)’构成的括号串,求有多少个合法的非空子串。

合法括号串的定义:

  1. 空串是合法括号串;

  2. 如果a是合法括号串,那么(a)也是合法括号串;

  3. 如果a,b是合法括号串,那么ab也是合法括号串。

Input

第一行一个整数T,表示数据组数。(T<=10)

接下来T行,每行一个括号串(长度<=5000)。

Output

对于每组测试数据,输出“Case #x: y”,其中x表示数据组数编号,y表示合法子串数。

Sample Input

2
(())(
)))(

Sample Output

Case #1: 2
Case #2: 0

思路:
先将字符串每个括号转换成数字,‘(’为1,‘)’为-1
设数组mark记录前缀和
两次循环,若mark[j] == mark[i]-1, 说明此时左右括号合法相等(遇到mark[j] < mark[i]-1时,说明多了右括号,退出当前循环)

反思:
1、开始时思维被束缚在字符串上,没有换个角度,先将其转换成数字来看,不够开拓;
2、求子串个数的方法有很多,其实这题只要想到可以循环求就好了,有些打了擦边球的念头被抛弃的太快,如果细细深入再琢磨一下的话就可以很快做出来

#include <bits/stdc++.h>
using namespace std;
const int maxn = 10010;
int mark[maxn];

int main()
{
    int t, cas = 1;
    scanf("%d", &t);
    while(t--){
        string str;  cin >> str;
        int len = str.length();
        for(int i = 0; i < len; i++)
            if(str[i] == '(')//******
                mark[i+1] = mark[i]+1;
            else
                mark[i+1] = mark[i]-1;
        int ans = 0;
        for(int i = 1; i <= len; i++){
            if(str[i-1] == '(')  //****** 子串都从左括号开始
            for(int j = i+1; j <= len; j++){
                if(mark[j] == mark[i]-1) ans++;
                else if(mark[j] < mark[i]-1) break;
            }
        }
        printf("Case #%d: %d\n", cas++, ans);
    }
    return 0;
}

Problem: 终极质数

Problem Description

质数是除了1和本身没有其他约数的数。

定义一个数字是终极质数当且仅当这个数所有数位的任意子序列构成的数都是质数,在这里我们把1也当成质数。比如17是终极质数,因为1,7,17都是质数,而19不是因为9不是质数。

给定一个整数n(2<=n<=10^100),求不大于n的最大终极质数。

Input

第一行一个整数T表示数据组数。(T<=10000)

接下来T行,每行一个整数n。

Output

每组数据输出”Case #x: y”,其中x是数据组数编号,y是答案。

Sample Input

2
6
100

Sample Output

Case #1: 5
Case #2: 73

思路:
先挑一位数: 1, 2, 3, 5, 7
以一位数为首,后面补可能的数,得二位数:
11, 13, 17, 23, 31, 37, 53, 71, 73
以二位数为首,后面补可能的一位数(此时只剩下1,3,7):
113, 131, 137, 173, 311, 317

反思:

概念不可想当然啊!!!
子序列不是你想的那个意思!!!!
ps:当程序觉得没有错处之后,请回头看题。。。

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

const int maxn = 1e6+1000;
int mark[maxn];
int ans[20] = {1, 2, 3,5,7,11,13,17,23,31,37,53,71,73,113,131,137,173,311,317};

int main()
{
    int t; cin >> t;
    int cas = 1;
    while(t--){
        double n;
        scanf("%lf", &n);
        for(int i = 19; i >= 0; i--)
            if(ans[i] <= n){
                printf("Case #%d: %d\n", cas++, ans[i]);
                break;
            }
    }
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值