CF #299 div2

A:

解析:

map乱搞一下就过了。

代码:

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <algorithm>
#include <cstring>
#include <cmath>
#include <stack>
#include <vector>
#include <queue>
#include <map>
#include <climits>
#include <cassert>
#define LL long long
#define lson lo, mi, rt << 1
#define rson mi + 1, hi, rt << 1 | 1

using namespace std;
const int maxn = 510;
const int inf = 0x3f3f3f3f;
const double eps = 1e-8;
const double pi = acos(-1.0);
const double ee = exp(1.0);

map<int, string> g;

void init()
{
    g[0] = "zero";
    g[1] = 	"one";
    g[11] = 	"eleven";
    g[2] =	"two";
    g[12] = 	"twelve";
    g[20] = 	"twenty";
    g[3] 	="three";
    g[13] 	="thirteen";
    g[30]  	="thirty";
    g[4] =	"four";
    g[14] 	="fourteen";
    g[40] 	="forty";
    g[5] 	="five";
    g[15] 	="fifteen";
    g[50] 	="fifty";
    g[6] 	="six";
    g[16] 	="sixteen";
    g[60] 	="sixty";
    g[7] 	="seven";
    g[17] = "seventeen";
    g[70] 	="seventy";
    g[8] 	="eight";
    g[18] 	="eighteen";
    g[80] 	="eighty";
    g[9] 	="nine";
    g[19] 	="nineteen";
    g[90] 	="ninety";
    g[10] = "ten";
}

int main()
{
#ifdef LOCAL
    freopen("in.txt", "r", stdin);
#endif // LOCAL
    init();
    int s;
    while (cin >> s)
    {
        if (g.find(s) == g.end())
        {
            int t = s % 10;
            cout << g[s - t] << "-" << g[t] <<endl;
        }
        else
        {
            cout << g[s] << endl;
        }
    }

    return 0;
}

B:

题意:

由7和4构成的数,由小到大构造,问输入一个数,是这个构造数列的第几个数。

解析:

将7和4看做是二进制的1和0,每种长度为n的数所有组合占用掉了1 << n个数,然后由二进制来算当前这个为第几个就好了。

也可以打表。

代码:

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <algorithm>
#include <cstring>
#include <cmath>
#include <stack>
#include <vector>
#include <queue>
#include <map>
#include <climits>
#include <cassert>
#define LL long long
#define lson lo, mi, rt << 1
#define rson mi + 1, hi, rt << 1 | 1

using namespace std;
const int maxn = 510;
const int inf = 0x3f3f3f3f;
const double eps = 1e-8;
const double pi = acos(-1.0);
const double ee = exp(1.0);

int main()
{
#ifdef LOCAL
    freopen("in.txt", "r", stdin);
#endif // LOCAL
    int n;
    cin >> n;
    int cnt = 0;
    LL ans = 0;
    while (n)
    {
        int t = n % 10;
        if (t == 7)
        {
            ans += (1LL << cnt);
        }
        n /= 10;
        cnt++;
    }
    for (int i = 0; i < cnt; i++)
    {
        ans += (1LL << i);
    }
    printf("%lld\n", ans);
    return 0;
}

C:

题意:

给一个等差数列的首项A和公差B,然后有n次询问。

每次询问输入一个左边界l,时间限制 t s,和每次可以-1的最大个数m。

m的定义是,每次1s可以挑选范围 l 到 r 中的1~m个数来-1,当当前这个数为0时代表吃完了。

然后要求一个最大的右边界r,要求在t的时间内 l 到 r 的等差数列的每一项都被吃完了。

解析:

O(n*logn)的算法,就是二分了。

可以减掉的总和是一定的,并且又是递增序列,只要限制最右边的数是低于给定时间t的就行了。

代码:

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <algorithm>
#include <cstring>
#include <cmath>
#include <stack>
#include <vector>
#include <queue>
#include <map>
#include <climits>
#include <cassert>
#define LL long long
#define lson lo, mi, rt << 1
#define rson mi + 1, hi, rt << 1 | 1

using namespace std;
const int maxn = 10000010;
const int inf = 0x3f3f3f3f;
const double eps = 1e-8;
const double pi = acos(-1.0);
const double ee = exp(1.0);

LL a, b, n;

int main()
{
#ifdef LOCAL
    freopen("in.txt", "r", stdin);
#endif // LOCAL
    scanf("%lld%lld%lld", &a, &b, &n);
    for (int i = 0; i < n; i++)
    {
        LL l, t, m;
        scanf("%lld%lld%lld", &l, &t, &m);
        if (a + (l - 1) * b > t)
        {
            printf("-1\n");
        }
        else
        {
            LL lo = l, hi = (t - a) / b + 1;
            LL key = m * t;
            while (lo <= hi)
            {
                LL mi = (lo + hi) >> 1;
                LL sum = (mi - l + 1) * (a + (l - 1) * b) + (mi - l + 1) * (mi - l) / 2 * b;
                if (sum <= key)
                    lo = mi + 1;
                else
                    hi = mi - 1;
            }
            cout << lo - 1 << endl;
        }

    }
    return 0;
}

D:

题意:

题意超难懂。

给一个原串的长度n,然后给出子串匹配原串的位置数m。

然后是字串。

然后是m个位置。

现在要求原串有多少种组成方法。

比如样例1:

6 2
ioi
1 3

可以这样表示“ ioioi?”,?处可以填入26个字母,所以总共构成原串的方法为26种。

解析:

有个很重要的点我理解错了:子串的定义,是由原串删掉一些字符与子串相等。

所以直接比较头一个字符是否相等就可以找出0的情况了。

然后只要数出有几个?,26的?次方取模就行了。

代码:

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <algorithm>
#include <cstring>
#include <cmath>
#include <stack>
#include <vector>
#include <queue>
#include <map>
#include <climits>
#include <cassert>
#define LL long long
#define lson lo, mi, rt << 1
#define rson mi + 1, hi, rt << 1 | 1

using namespace std;
const int maxn = 1000010;
const int inf = 0x3f3f3f3f;
const double eps = 1e-8;
const double pi = acos(-1.0);
const double ee = exp(1.0);

int n, m;
bool vis[maxn];
char p[maxn];
int f[maxn];

int main()
{
#ifdef LOCAL
    freopen("in.txt", "r", stdin);
#endif // LOCAL
    memset(vis, false, sizeof(vis));
    scanf("%d%d", &n, &m);
    scanf("%s", p);
    int len = strlen(p);
    bool flag = false;
    int x1 = -1;
    while (m--)
    {
        int x2;
        scanf("%d", &x2);
        if (x1 == -1)
        {
            n -= len;
        }
        else
        {
            if (x2 - x1 < len)
            {
                if (p[0] != p[x2 - x1])
                {
                    flag = true;
                }
                else
                {
                    n -= x2 - x1;
                }
            }
            else
            {
                n -= len;
            }
        }
        x1 = x2;
    }
    if (flag)
    {
        printf("0\n");
    }
    else
    {
        LL ans = 1;
        for (int i = 1; i <= n; i++)
        {
            ans = (ans * 26) % 1000000007;
        }
        printf("%I64d\n", ans);
    }
    return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值