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;
}