西安电子科技大学第16届程序设计竞赛网络同步赛 E dp G 找规律

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\n", 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 是 \10 且 n 是 2 的次方数情况,要多加一个。。。 ``` #include 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;
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*2
tmp) s2=get(s1);
}
printf("%d\n", ans);
}

return 0;

}

posted @ 2018-04-21 18:19  v9fly  阅读(121)  评论(0编辑  收藏  举报