1.计数问题
算法分析
剥数。
#include <iostream>
#include <cstdio>
#include <cstring>
#define ll long long
using namespace std;
int main() // 剥数
{
int n, x;
scanf("%d%d", &n, &x);
int sum = 0;
for (int i = 1; i <= n; ++i)
{
int t = i;
while (t)
{
if (t % 10 == x) ++sum;
t /= 10;
}
}
printf("%d\n", sum);
return 0;
}
2.表达式求值
算法分析
有一个取巧的读入方式。仔细观察数据特点,第一个数据是数字,第二个是运算符,第三个也是数字,后面就是运算符和数字成对出现了。可以用 w h i l e + s c a n f while + scanf while+scanf读入不定个数的数字。读入的时候,遇到数字就入栈,遇到乘号就从栈顶弹出两个数相乘,然后结果再入栈。因为只有加号和乘号,最后栈里的数据都是要相加的,加起来就是答案。每一步都要模10000。
#include <iostream>
#include <cstdio>
#include <cstring>
#include <stack>
#define ll long long int
using namespace std;
const int P = 10000;
stack<ll> s;
int main()
{
char c;
ll a;
scanf("%lld", &a);
s.push(a % P);
while (scanf("%c%lld", &c, &a) == 2) // 读入不定个数
{
if (c == '*')
{
ll u = s.top(); s.pop();
s.push(a % P * u % P);
}else s.push(a % P);
}
ll ans = 0;
while (s.size())
{
ans += s.top();
ans %= P;
s.pop();
}
printf("%lld\n", ans % P);
return 0;
}
算法拓展
1.递归求中缀表达式。对于区间 [ l , r ] [l, r] [l,r],每次从右侧找第一个加号,左右两侧的结果加起来。如果没有加号,找右数第一个乘号,结果乘起来。如果加号和乘号都没有,说明这是一个数字,直接返回。
利用前缀和,迅速判断区间内是否有加号或乘号。有一个注意事项:加号和乘号最多有10万个,每个符号配一个数字,数字的字符个数未知,不好开数组。开小了会RE。开1000万能过。
#include <iostream>
#include <cstdio>
#include <cstring>
#include <stack>
#define ll long long
using namespace std;
const int P = 10000;
char s[10000010];
int sumjia[10000010], sumcheng[10000010];
int dfs(int l, int r)
{
if (sumjia[r] - sumjia[l-1] == 0 && sumcheng[r] - sumcheng[l-1] == 0)
{
int x = 0;
for (int i = l; i <= r; ++i) x = x * 10 + s[i] - '0';
return x % P;
}
if (sumjia[r] - sumjia[l-1] == 0)
{
int i;
for (i = r; i >= l; --i) if (s[i] == '*') break;
return dfs(l, i-1) % P * dfs(i+1, r) % P;
}else
{
int i;
for (i = r; i >= l; --i) if (s[i] == '+') break;
return (dfs(l, i-1) % P + dfs(i+1, r) % P) % P;
}
}
int main()
{
scanf("%s", s + 1);
int n = strlen(s+1);
for (int i = 1; i <= n; ++i)
{
if (s[i] == '+') sumjia[i] = sumjia[i-1] + 1;
else sumjia[i] = sumjia[i-1];
if (s[i] == '*') sumcheng[i] = sumcheng[i-1] + 1;
else sumcheng[i] = sumcheng[i-1];
}
printf("%d\n", dfs(1, n));
return 0;
}
2.sscanf。