https://www.nowcoder.com/acm/contest/107#question
E Xieldy And His Password
题意:
给出一段 01 字符串,问有多少个子串满足:
1. 口令串表示的二进制数在十进制下可以被表示为3k(k>=0)。
2. 口令串可以有前导零。
tags:
考虑 dp[i][0] 、dp[i][1]、dp[i][2] 分别为以第 i 个字符结尾,模 3 得 0、1、2 的数量,然后递推转移即可。
#include<bits/stdc++.h>
using namespace std;
#pragma comment(linker, "/STACK:102400000,102400000")
#define rep(i,a,b) for (int i=a; i<=b; ++i)
#define per(i,b,a) for (int i=b; i>=a; --i)
#define mes(a,b) memset(a,b,sizeof(a))
#define INF 0x3f3f3f3f
#define MP make_pair
#define PB push_back
#define fi first
#define se second
typedef long long ll;
const int N = 2000005;
int len;
ll ans, dp[N][3];
char s[N];
void Init() {
mes(dp, 0); ans = 0;
}
int main()
{
while(~scanf("%s", s+1))
{
Init();
len = strlen(s+1);
rep(i,1,len)
{
if(s[i]=='0')
{
dp[i][0] = 1;
dp[i][0] += dp[i-1][0];
dp[i][1] += dp[i-1][2];
dp[i][2] += dp[i-1][1];
}
else
{
dp[i][1] = 1;
dp[i][0] += dp[i-1][1];
dp[i][1] += dp[i-1][0];
dp[i][2] += dp[i-1][2];
}
ans += dp[i][0];
}
printf("%lld
", ans);
}
return 0;
}
###G 小国的复仇 题意: 初始 s1=1,s2=1 , 有两个操作: 1】 s1+=s2, s2=s2; 2】 s2=s1, s1*=2 。 T (T<=100000)个询问,每次问要把 s1 变到 n (n<=10^6) 最少要多少次操作。 tags: 打表找规律水过去了。。 发现对于每个 s1,当前最优的 s2 是
const int N = 2000005;
bool mark[N];
void sieve_prime()
{
memset(mark, true, sizeof(mark));
mark[0] = mark[1] = false;
for(int i=2; i<=sqrt(N); i++) {
if(mark[i]) {
for(int j=i*i; j<N; j+=i)
mark[j]=false;
}
}
}
int get(int x) {
for(ll i=2; i*i<=x; ++i) if(x%i==0) return x/i;
return 1;
}
int T, n;
int main()
{
sieve_prime();
scanf("%d", &T);
while(T--)
{
scanf("%d", &n);
int s1 = n;
int ans = 0, s2=get(s1);
if((s1&(s1-1))0 && s1>10) ans = 1;
while(s1>1)
{
if(mark[s1]) {
ans += s1-1; break;
}
++ans;
int tmp = s1;
s1 -= s2;
if(s2*2tmp) s2=get(s1);
}
printf("%d
", ans);
}
return 0;
}