muti多校7 & 2017百度之星复赛

muti多校7 & 2017百度之星复赛

HDU 6129

题目要求

求原数组m次xor前缀和后的数组

参考AC代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
#include<bits/stdc++.h>
#define maxn 200050
#define mm(a,b) memset(a,b,sizeof(a))
using namespace std;
int a[maxn],b[maxn];
int main(){
// freopen("input.txt","r",stdin);
int t;
scanf("%d",&t);
while(t--){
int n,m;
scanf("%d%d",&n,&m);
mm(b,0);
for(int i=1;i<=n;i++) scanf("%d",&a[i]);
for(int i=1;i<=n;i++){
int x=i+m-2;
int y=i-1;
if((x&y)==y){
for(int j=i;j<=n;j++) b[j]^=a[j-i+1];
}
}
for(int i=1;i<=n;i++){
if(i==1) printf("%d",b[i]);
else printf(" %d",b[i]);
}
printf("\n");
}
return 0;
}

思路

转跳链接
考虑第一个位置对后面每一个位置的影响 可以推出这是杨辉三角
根据杨辉三角的公式判断奇偶性 xor奇数次才有效
第二个位置开始与第一个位置相同 所以不需要另推 按照间隔递推即可

HDU 6144

题目要求

Bomb Number中的bomb,也就是#号,会展开一些数字,这会导致最终展开的数字超出了度度熊所能理解的范畴。比如”(1)#(3)”表示”1”出现了3次,将会被展开为”111”,
同理,”(12)#(2)4(2)#(3)”将会被展开为”12124222”。
请将Bomb Number中所有的#号展开,由于数字可能很长,结果对 1 000 000 007 取模。

第一行为T,表示输入数据组数。
每组数据包含一个Bomb Expression。

  • 1≤T≤100
  • 1≤length(Bomb Number)≤1000

对每组数据输出表达式的结果,结果对 1 000 000 007 取模。

参考AC代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
#include<bits/stdc++.h>
#define maxn 100050
#define LL long long
#define mm(a,b) memset(a,b,sizeof(a))
using namespace std;
const LL mod=1e9+7;
vector<int>e;
int main(){
// freopen("input.txt","r",stdin);
int t;
scanf("%d",&t);
while(t--){
e.clear();
string s;
cin>>s;
int len=s.length();
int st=-1,ed=-1;
int flag=-1;
int num=0;
for(int i=0;i<len;i++){
if(s[i]=='('){
if(flag==-1) flag=1;
}
if(s[i]>='0' && s[i]<='9'){
if(flag==-1) e.push_back(s[i]-'0');
else if(flag==1){
if(st==-1) st=i,ed=i;
else ed++;
}
else{
num=num*10+s[i]-'0';
}
}
if(s[i]=='#') flag=2;
if(s[i]==')' && flag==2){
for(int k=1;k<=num;k++){
for(int j=st;j<=ed;j++) e.push_back(s[j]-'0');
}
flag=-1,num=0,st=-1,ed=-1;
}
}
LL ans=0;
for(int i=0;i<e.size();i++){
ans=(((ans*10)%mod+e[i])%mod)%mod;
}
cout<<ans<<endl;
}
return 0;
}

思路

模拟
st和ed记录要存入vector的数字 num记录次数 注意存在数字不在括号里的情况 这里用flag是否为-1特判
flag==2说明进入记录出现多少次的阶段

HDU 6148

题目要求

当一个数字,从左到右依次看过去数字没有出现先递增接着递减的“山峰”现象,就被称作 Valley Number。它可以递增,也可以递减,还可以先递减再递增。在递增或递减的过程中可以出现相等的情况。
比如,1,10,12,212,32122都是 Valley Number。
121,12331,21212则不是。
度度熊想知道不大于N的Valley Number数有多少。
注意,前导0是不合法的。

第一行为T,表示输入数据组数。
每组数据包含一个数N。
● 1≤T≤200
● 1≤length(N)≤100

对每组数据输出不大于N的Valley Number个数,结果对 1 000 000 007 取模。

参考AC代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
#include<bits/stdc++.h>
#define maxn 100050
#define LL long long
#define mm(a,b) memset(a,b,sizeof(a))
using namespace std;
const LL mod = 1e9+7;
int dp[105][15][2];
char s[105];
int bit[105];
LL dfs(int pos,int status,int pre,int limit){
if(pos<1) return 1;
if(!limit && dp[pos][pre][status]!=-1) return dp[pos][pre][status];
int end=limit? bit[pos]:9;
LL ans=0;
if(status){
for(int i=pre;i<=end;i++){
ans+=dfs(pos-1,1,i,limit&&i==end);
ans%=mod;
}
}
else{
for(int i=0;i<=end;i++){
if(i>pre) ans+=dfs(pos-1,1,i,limit&&i==end);
else{
if(!i && pre==10) ans+=dfs(pos-1,0,10,limit&&i==end);
else ans+=dfs(pos-1,0,i,limit&&i==end);
}
ans%=mod;
}
}
if(!limit) dp[pos][pre][status]=ans;
return ans;
}
int main(){
// freopen("input.txt","r",stdin);
mm(dp,-1);
int t; scanf("%d",&t);
while(t--){
scanf("%s",&s);
int len=strlen(s);
mm(bit,0);
for(int i=0;i<len;i++) bit[len-i]=s[i]-'0';
LL ans=dfs(len,0,10,1);
cout<<ans-1<<endl;
}
return 0;
}

思路

数位dp裸题 记忆化搜索
dp表示dp[位置][前一个数字][状态:0下降 1:上升]
注意前导0的特判 pre=10代表前一位不存在 即该位置为前导0 所以直接pos-1进行下一位判断
跟普通的数位dp相比多了一个对status的判断 status=1后不能下降

文章目录
  1. 1. muti多校7 & 2017百度之星复赛
    1. 1.1. HDU 6129
      1. 1.1.1. 题目要求
      2. 1.1.2. 参考AC代码
      3. 1.1.3. 思路
    2. 1.2. HDU 6144
      1. 1.2.1. 题目要求
      2. 1.2.2. 参考AC代码
      3. 1.2.3. 思路
    3. 1.3. HDU 6148
      1. 1.3.1. 题目要求
      2. 1.3.2. 参考AC代码
      3. 1.3.3. 思路
|