[SinGuLaRiTy] 2017 百度之星程序设计大赛 复赛
【SinGuLaRiTy-1038】 Copyright (c) SinGuLaRiTy 2017. All Rights Reserved.
Arithmetic of Bomb
Problem Description
众所周知,度度熊非常喜欢数字。
它最近在学习小学算术,第一次发现这个世界上居然存在两位数,三位数……甚至N位数!
但是这回的算术题可并不简单,由于含有表示bomb的#号,度度熊称之为 Arithmetic of Bomb。
Bomb Number中的bomb,也就是#号,会展开一些数字,这会导致最终展开的数字超出了度度熊所能理解的范畴。比如”(1)#(3)”表示”1”出现了3次,将会被展开为”111”,
同理,”(12)#(2)4(2)#(3)”将会被展开为”12124222”。
为了方便理解,下面给出了Bomb Number的BNF表示。
```
<bomb number> := <bomb term> | <bomb number> <bomb term>
<bomb term> := <number> | '(' <number> ')' '#' '(' <non-zero-digit> ')'
<number> := <digit> | <digit> <number>
<digit> := '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9'
<non-zero-digit> := '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9'
```
请将Bomb Number中所有的#号展开,由于数字可能很长,结果对 1 000 000 007 取模。
Input
第一行为T,表示输入数据组数。
每组数据包含一个Bomb Expression。
- 1≤T≤100
- 1≤length(Bomb Number)≤1000
Output
对每组数据输出表达式的结果,结果对 1 000 000 007 取模。
Sample Input
4
1
(1)#(3)
(12)#(2)4(2)#(3)
(12)#(5)
Sample Output
1
111
12124222
212121205
Code
模拟,签到题不解释。
- #include<cstdio>
- #include<cstring>
- #include<cctype>
- #include<cmath>
- #include<algorithm>
- #define ll long long
- #define inf 0x3f3f3f3f
- #define maxn 101000
- #define MOD 1000000007
- using namespace std;
- int read()
- {
- char c;int s=,t=;
- while(!isdigit(c=getchar()))if(c=='-')t=-;
- do{s=s*+c-'';}while(isdigit(c=getchar()));
- return s*t;
- }
- int n;
- char s[maxn],ans[maxn],nows[maxn];
- int main()
- {
- int T;
- scanf("%d",&T);
- while(T--)
- {
- scanf("%s",s+);
- int n=strlen(s+);
- int nowstep=,len=,tot=;
- for(int i=;i<=n;i++)if(isdigit(s[i]))
- {
- if(nowstep==){nows[++len]=s[i];}
- else
- if(nowstep==)
- {
- for(int j=;j<=s[i]-'';j++)
- for(int k=;k<=len;k++)
- ans[++tot]=nows[k];
- len=;nowstep=;
- }
- else
- if(nowstep==)ans[++tot]=s[i];
- }
- else
- {
- if(nowstep==&&s[i]=='(')
- nowstep=;
- else if(nowstep==&&s[i]==')')
- nowstep=;
- }
- long long ansnum=;
- for(int i=;i<=tot;i++)
- ansnum=(ansnum*+ans[i]-'')%MOD;
- printf("%lld\n",ansnum);
- }
- return ;
- }
Arithmetic of Bomb II
Problem Descroption
众所周知,度度熊非常喜欢数字。
它最近在学习小学算术,沉迷于计算A+B中不能自拔。
但是这回的算术题可并不简单,由于含有表示bomb的#号,度度熊称之为 Arithmetic of Bomb。
Arithmetic of Bomb的目的与普通算术一样,就是计算一些Bomb Expression的结果。比如,”1-2+3”的结果为2。然而,bomb,也就是#号,会展开一些普通表达式,这会导致需要计算的式子超出了度度熊所能理解的范畴。比如”(1-2+3)#(3)”表示”1-2+3”出现了3次,将会被展开为”1-2+31-2+31-2+3”。
为了方便理解,下面给出了Bomb Expression的BNF表示。
```
<bomb expression> := <bomb term> | <bomb expression> <bomb term>
<bomb term> := <bomb statement> | '(' <bomb statement> ')' '#' '(' <number> ')'
<bomb statement> := <bomb element> | <bomb statement> <bomb element>
<bomb element> := <digit> | '+' | '-' | '*'
<normal expression> := <norm term> | <normal expression> '+' <norm term> | <normal expression> '-' <norm term>
<norm term> := <number> | <norm term> '*' <number>
<number> := <digit> | <non-zero-digit> <number>
<digit> := '0' | <non-zero-digit>
<non-zero-digit> := '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9'
```
请先将Bomb Expression中所有的#号展开,使其成为Normal Expression(题目的输入保证展开后是一个合法的Normal Expression),再来计算这个表达式的结果。
Input
第一行为T,表示输入数据组数。
每组数据包含一个Bomb Expression。
●1≤T≤50
●1≤length(Bomb Statement)≤10
●1≤length(Number in Bomb term)≤10
●1≤length(Bomb Expression)≤300 000
Output
对每组数据输出表达式的结果,结果对 1 000 000 007 取模。
Sample Input
6
1-2+3
(1-2+3)#(3)
(1)#(3)
(1+)#(2)1
(2*3+1)#(2)
(2)#(2)1+1(2)#(2)
Sample Output
2
60
111
3
43
343
Code
我还不会矩阵运算呀,只好先在这里放一放大牛的代码了(能做出这道题的确佩服!)
【本题题解来自于:y5zsq】
Code
- #include<cstdio>
- #include<iostream>
- #include<cstring>
- #include<algorithm>
- #include<cmath>
- #include<vector>
- #include<queue>
- using namespace std;
- typedef long long ll;
- #define maxn 300005
- #define mod 1000000007
- vector<string>term;
- vector<ll>num;
- char c[maxn];
- int T;
- void Deal()
- {
- term.clear(),num.clear();
- int n=strlen(c);
- for(int i=;i<n;)
- {
- string s;
- if(c[i]=='(')
- {
- i++;
- while(c[i]!=')')s.push_back(c[i++]);
- i+=;
- ll t=;
- while(c[i]!=')')t=t*+c[i++]-'';
- if(t)term.push_back(s),num.push_back(t);
- i++;
- }
- else
- {
- while(i<n&&c[i]!='(')s.push_back(c[i++]);
- term.push_back(s),num.push_back();
- }
- }
- }
- typedef ll Mat[][];
- Mat A,B,C;
- void Mul(Mat &a,Mat b)
- {
- Mat c;
- for(int i=;i<;i++)
- for(int j=;j<;j++)
- {
- c[i][j]=;
- for(int k=;k<;k++)
- c[i][j]+=a[i][k]*b[k][j];
- }
- for(int i=;i<;i++)
- for(int j=;j<;j++)
- a[i][j]=(c[i][j]%mod+mod)%mod;
- }
- void Pow(Mat &a,ll b)
- {
- if(b==)return ;
- Mat c;
- for(int i=;i<;i++)
- for(int j=;j<;j++)
- c[i][j]=(i==j);
- while(b)
- {
- if(b&)Mul(c,a);
- Mul(a,a);
- b>>=;
- }
- for(int i=;i<;i++)
- for(int j=;j<;j++)
- a[i][j]=c[i][j];
- }
- ll Count()
- {
- for(int i=;i<;i++)
- for(int j=;j<;j++)
- A[i][j]=(i==j);
- int sign=;
- for(int k=;k<term.size();k++)
- {
- string s=term[k];
- ll t=num[k];
- int n=s.size();
- for(int i=;i<;i++)
- for(int j=;j<;j++)
- B[i][j]=(i==j);
- for(int i=;i<n;i++)
- {
- memset(C,,sizeof(C));
- C[][]=C[][]=;
- if(s[i]>=''&&s[i]<='')
- C[][]=,C[][]=s[i]-'',C[][]=;
- else if(s[i]=='+')
- C[][]=sign,C[][]=,sign=;
- else if(s[i]=='-')
- C[][]=sign,C[][]=,sign=-;
- else C[][]=;
- Mul(B,C);
- }
- Mul(A,B);
- if(t>)
- {
- for(int i=;i<;i++)
- for(int j=;j<;j++)
- B[i][j]=(i==j);
- for(int i=;i<n;i++)
- {
- memset(C,,sizeof(C));
- C[][]=C[][]=;
- if(s[i]>=''&&s[i]<='')
- C[][]=,C[][]=s[i]-'',C[][]=;
- else if(s[i]=='+')
- C[][]=sign,C[][]=,sign=;
- else if(s[i]=='-')
- C[][]=sign,C[][]=,sign=-;
- else C[][]=;
- Mul(B,C);
- }
- Pow(B,t-);
- Mul(A,B);
- }
- }
- ll ans=(A[][]+A[][])%mod;
- if(sign==)ans=(ans+A[][]+A[][])%mod;
- else ans=(ans-A[][]-A[][])%mod;
- ans=(ans+mod)%mod;
- return ans;
- }
- int main()
- {
- scanf("%d",&T);
- while(T--)
- {
- scanf("%s",c);
- Deal();
- printf("%I64d\n",Count());
- }
- return ;
- }
Pokémon GO
Problem Description
众所周知,度度熊最近沉迷于 Pokémon GO。
今天它决定要抓住所有的精灵球!
为了不让度度熊失望,精灵球已经被事先放置在一个2*N的格子上,每一个格子上都有一个精灵球。度度熊可以选择任意一个格子开始游戏,抓捕格子上的精灵球,然后移动到一个相邻的至少有一个公共点的格子上继续抓捕。例如,(2, 2) 的相邻格子有(1, 1), (2, 1) 和 (1, 2) 等等。
现在度度熊希望知道将所有精灵球都抓到并且步数最少的方案数目。两个方案被认为是不同,当且仅当两个方案至少有一步所在的格子是不同的。
Input
第一行为T,表示输入数据组数。
每组数据包含一个数N。
●1≤T≤100
●1≤N≤10000
Output
对每组数据输出方案数目,结果对 1 000 000 007 取模。
Sample Input
3
1
2
3
Sample Input
2
24
96
Code
动态规划
- #include<cstdio>
- #include<cmath>
- #include<cstdlib>
- #include<algorithm>
- #include<iostream>
- #include<cstring>
- #define ll long long
- const int maxn=,MOD=;
- ll a[maxn],b[maxn],n;
- int main()
- {
- b[]=;
- for(int i=;i<=maxn;i++)
- b[i]=(b[i-]*)%MOD;
- a[]=;
- a[]=;
- for(int i=;i<=maxn;i++)
- a[i]=(*a[i-]+b[i]+*a[i-])%MOD;
- int T;
- scanf("%d",&T);
- while(T--)
- {
- int n;
- scanf("%d",&n);
- ll ans=;
- for(int i=;i<=n-;i++)
- ans=(ans+*b[i-]%MOD*a[n-i])%MOD;
- ans=(ans+*a[n])%MOD;
- if(n==)
- ans=;
- printf("%lld\n",ans);
- }
- return ;
- }
Pokémon GO II
Problem Description
众所周知,度度熊最近沉迷于 Pokémon GO。
由于太过沉迷,现在它只能按照游戏内置的指令行走了:对,简直就像一个现实中的Pokémon!
游戏内置的指令实际上可以抽象成一种:保持现在的朝向前行X米,然后右转。度度熊相信,只要遵循这个指令,它就一定可以抓到最珍奇的精灵球。
但不幸的是,这个指令并不是很有可信度,有时会引导度度熊走回原来的位置。现在它想知道,在第几条指令时它第一次回到已经走过的位置?如果这种情况没有发生,请输出 “Catch you”。
Input
第一行为T,表示输入数据组数。
每组数据的第一行包含一个数N,表示指令长度。接着的一行包含N个数字Xi,表示第i个指令中前行的距离。
● 1≤T≤100
● 1≤N≤1 000 000
● 1≤Xi≤1 000 000 000
Output
对每组数据输出第一次回到已经走过的位置时的指令下标i (1≤i≤N)。
如果这种情况没有发生,请输出 “Catch you”。
Sample Input
3
4
2 2 2 2
4
2 1 3 1
5
2 1 3 1 3
Sample Output
4
Catch you
5
Code
目测几何神犇题,发现可以画画图找规律......第一次覆盖一定发生在轨迹的前8段中。
- #include<cstdio>
- #include<algorithm>
- #include<cstdlib>
- #include<cmath>
- #include<iostream>
- #include<cstdlib>
- #define MAXN 1000010
- using namespace std;
- const int dx[]={,,,-},dy[]={,,-,};
- int N,a[MAXN];
- struct Point
- {
- int x,y;
- Point(int _x=,int _y=):x(_x),y(_y){}
- }points[MAXN];
- bool overlap(int a,int b,int c,int d)
- {
- if(a>b)
- swap(a, b);
- if(c>d)
- swap(c, d);
- return !(b<c||d<a);
- }
- bool intersect(Point a1,Point a2,Point b1,Point b2)
- {
- bool is_vertical_a=(a1.x==a2.x),is_vertical_b=(b1.x==b2.x);
- if(is_vertical_a && is_vertical_b)
- return a1.x==b1.x&&overlap(a1.y,a2.y,b1.y,b2.y);
- if(!is_vertical_a && !is_vertical_b)
- return a1.y==b1.y&&overlap(a1.x,a2.x,b1.x,b2.x);
- if(is_vertical_a)
- {
- swap(a1,b1);
- swap(a2,b2);
- }
- return !(max(a1.x,a2.x)<b1.x||min(a1.x,a2.x)>b1.x||max(b1.y,b2.y)<a1.y||min(b1.y,b2.y)>a1.y);
- }
- int solve()
- {
- int x=,y=;
- for(int i=;i<N;++i)
- {
- x+=dx[i&]*a[i];
- y+=dy[i&]*a[i];
- points[i+].x=x;
- points[i+].y=y;
- for(int j=max(,i-);j<i-;++j)
- if(intersect(points[j],points[j+],points[i],points[i+]))
- return i;
- }
- return -;
- }
- int main()
- {
- int T;
- scanf("%d", &T);
- while(T--)
- {
- scanf("%d",&N);
- for(int i=;i<N;++i)
- scanf("%d",a+i);
- int result=solve();
- if(result==-)
- printf("Catch you\n");
- else
- printf("%d\n", result+);
- }
- return ;
- }
Valley Numer
Problem Description
众所周知,度度熊非常喜欢数字。
它最近发明了一种新的数字:Valley Number,像山谷一样的数字。
当一个数字,从左到右依次看过去数字没有出现先递增接着递减的“山峰”现象,就被称作 Valley Number。它可以递增,也可以递减,还可以先递减再递增。在递增或递减的过程中可以出现相等的情况。
比如,1,10,12,212,32122都是 Valley Number。
121,12331,21212则不是。
度度熊想知道不大于N的Valley Number数有多少。
注意,前导0是不合法的。
Input
第一行为T,表示输入数据组数。
每组数据包含一个数N。
● 1≤T≤200
● 1≤length(N)≤100
Output
对每组数据输出不大于N的Valley Number个数,结果对 1 000 000 007 取模。
Sample Input
3
3
14
120
Sample Input
Code
记忆化搜索/数位DP
- #include<cstdio>
- #include<algorithm>
- #include<cstring>
- #include<cctype>
- #define ll long long
- using namespace std;
- const ll maxn=,MOD=;
- ll f[maxn][][],a[maxn],n;
- char s[maxn];
- ll dfs(ll pos,ll state,ll limit,ll pre)
- {
- if(pos==-)
- {
- if(~pre)
- return ;
- else
- return ;
- }
- if(!limit&&~pre&&~f[pos][state][pre])
- return f[pos][state][pre];
- ll up=limit?a[pos]:;
- ll ans=;
- for(int i=;i<=up;i++)
- {
- if(pre==-&&i==)
- ans=(ans+dfs(pos-,state,limit&&i==up,pre))%MOD;
- else if(pre==-&&i!=)
- ans=(ans+dfs(pos-,state,limit&&i==up,i))%MOD;
- else if(state==)
- ans=(ans+dfs(pos-,i>pre,limit&&i==up,i))%MOD;
- else if(state==&&i>=pre)
- ans=(ans+dfs(pos-,state,limit&&i==up,i))%MOD;
- }
- if(!limit&&~pre)
- f[pos][state][pre]=ans;
- return ans;
- }
- int main()
- {
- ll T;
- scanf("%lld",&T);
- memset(f,-,sizeof(f));
- while(T--)
- {
- scanf("%s",s+);
- n=strlen(s+);
- for(int i=;i<=n;i++)
- a[n-i]=s[i]-'';
- printf("%lld\n",dfs(n-,,,-));
- }
- return ;
- }
Valley Numer II
Problem Description
众所周知,度度熊非常喜欢图。
它最近发现了图中也是可以出现 valley —— 山谷的,像下面这张图。
为了形成山谷,首先要将一个图的顶点标记为高点或者低点。标记完成后如果一个顶点三元组<X, Y, Z>中,X和Y之间有边,Y与Z之间也有边,同时X和Z是高点,Y是低点,那么它们就构成一个valley。
度度熊想知道一个无向图中最多可以构成多少个valley,一个顶点最多只能出现在一个valley中。
Input
第一行为T,表示输入数据组数。
每组数据的第一行包含三个整数N,M,K,分别表示顶点个数,边的个数,标记为高点的顶点个数。
接着的M行,每行包含两个两个整数Xi,Yi,表示一条无向边。
最后一行包含K个整数Vi,表示这些点被标记为高点,其他点则都为低点。
● 1≤T≤20
● 1≤N≤30
● 1≤M≤N*(N-1)/2
● 0≤K≤min(N,15)
● 1≤Xi, Yi≤N, Xi!=Yi
● 1≤Vi≤N
Output
对每组数据输出最多能构成的valley数目。
Sample Input
View Sample Input
Sample Output
1
0
2
Code
状压DP
- #include<cstdio>
- #include<cstring>
- #include<cctype>
- #include<cmath>
- #include<algorithm>
- #define ll long long
- using namespace std;
- int read()
- {
- char c;int s=,t=;
- while(!isdigit(c=getchar()))if(c=='-')t=-;
- do{s=s*+c-'';}while(isdigit(c=getchar()));
- return s*t;
- }
- const int inf=0x3f3f3f3f,maxn=,maxk=;
- int n,f[][maxk],c,k,m,hi[maxn];
- bool Map[maxn][maxn],high[maxn];
- void dfs(int dep,int now,int pre,int cyc,int x)
- {
- if(dep==)
- f[now][c]=max(f[now][c],f[pre][cyc]+);
- else
- for(int i=;i<=k-;i++)
- if(Map[x][hi[i+]]&&!(c&(<<i)))
- {
- c|=(<<i);
- dfs(dep+,now,pre,cyc,x);
- c^=(<<i);
- }
- }
- int main()
- {
- int T;
- scanf("%d",&T);
- while(T--)
- {
- n=read();m=read();k=read();
- int u,v;
- memset(Map,,sizeof(Map));
- for(int i=;i<=m;i++)
- {
- u=read();v=read();
- Map[u][v]=Map[v][u]=;
- }
- memset(high,,sizeof(high));
- for(int i=;i<=k;i++)
- {
- u=read();
- high[u]=;
- }
- int nowk=;
- for(int i=;i<=n;i++)if(high[i])hi[++nowk]=i;
- k=nowk;
- memset(f,,sizeof(f));
- int x=;
- for(int i=;i<=n;i++)if(!high[i])
- {
- x=-x;
- memset(f[x],,sizeof(f[x]));
- for(int j=;j<(<<k);j++)
- {
- f[x][j]=max(f[x][j],f[-x][j]);
- c=j;
- dfs(,x,-x,j,i);
- }
- }
- int ans=;
- for(int i=;i<(<<k);i++)ans=max(ans,f[x][i]);
- printf("%d\n",ans);
- }
- return ;
- }
Time: 2017-08-24
[SinGuLaRiTy] 2017 百度之星程序设计大赛 复赛的更多相关文章
- 2017"百度之星"程序设计大赛 - 复赛1005&&HDU 6148 Valley Numer【数位dp】
Valley Numer Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Tota ...
- 2017"百度之星"程序设计大赛 - 复赛1003&&HDU 6146 Pokémon GO【数学,递推,dp】
Pokémon GO Time Limit: 3000/1500 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total ...
- 2017"百度之星"程序设计大赛 - 复赛1001&&HDU 6144 Arithmetic of Bomb【java大模拟】
Arithmetic of Bomb Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Other ...
- 2017"百度之星"程序设计大赛 - 复赛 01,03,05
Arithmetic of Bomb Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Other ...
- [SinGuLaRiTy] 2017 百度之星程序设计大赛 初赛A
[SinGuLaRiTy-1036] Copyright (c) SinGuLaRiTy 2017. All Rights Reserved. 小C的倍数问题 Time Limit: 2000/100 ...
- [SinGuLaRiTy] 2017 百度之星程序设计大赛 初赛B
[SinGuLaRiTy-1037] Copyright (c) SinGuLaRiTy 2017. All Rights Reserved. Chess Time Limit: 2000/1000 ...
- [SinGuLaRiTy] 2017 百度之星程序设计大赛-资格赛
[SinGuLaRiTy-1034] Copyright (c) SinGuLaRiTy 2017. All Rights Reserved. 度度熊保护村庄 Time Limit: 2000/10 ...
- 2017百度之星程序设计大赛 - 复赛 Arithmetic of Bomb
http://acm.hdu.edu.cn/showproblem.php?pid=6144 解法:一个简单的模拟 #include <bits/stdc++.h> using names ...
- 2017"百度之星"程序设计大赛 - 复赛
Arithmetic of Bomb Accepts: 1050 Submissions: 1762 Time Limit: 2000/1000 MS (Java/Others) Memory ...
随机推荐
- vs2017 android demo
vs2017自安装以后就没怎么打开过,虽然12出的时候用10,15出的时候用13,17出的时候用15,但我依然坚持不用也装上再说的理念. 1.vs2017开发IOS和Android安装所必不可少的,u ...
- ll | wc -l的陷阱
在平时我们可能经常使用ls和wc命令来统计某个文件夹下指定类型文件的个数.今天在使用的时候发现ls和ll出来的结果不一样. dwapp@pttest1:/home/dwapp/joe.wangh/te ...
- 虚拟机之 搭建discuz论坛
1.下载 mkdir /data/www cd !$ wget http://download.comsenz.com/DiscuzX/3.2/Discuz_X3.2_SC_GBK.zip 2.解压 ...
- java8新特性-lambda表达式和stream API的简单使用
一.为什么使用lambda Lambda 是一个 匿名函数,我们可以把 Lambda表达式理解为是 一段可以传递的代码(将代码像数据一样进行传递).可以写出更简洁.更灵活的代码.作为一种更紧凑的代码风 ...
- jvm的GC日志分析 [转]
jvm的GC日志分析 标签: jvm内存javagc 2015-06-22 16:37 1566人阅读 评论(1) 收藏 举报 分类: Java(4) JVM的GC日志的主要参数包括如下几个: ...
- Tornado 类与类组合降低耦合
- Xcode迁移工程常见问题
[Xcode迁移工程常见问题] 1.Header Search Paths (HEADER_SEARCH_PATHS) 是否设置正确.在Search Paths group下. 2.Framework ...
- iis8不支持 aspnet_regiis.exe -iru 命令的解决办法
服务器版的限制,我看你给的提示说也可以使用 dism.exe 命令行. C:\> DISM /Online /Enable-Feature /FeatureName:WCF-HTTP-Activ ...
- AOP基本概念、AOP底层实现原理、AOP经典应用【事务管理、异常日志处理、方法审计】
1 什么是AOP AOP为Aspect Oriented Programming的缩写,意为:面向切面编程,通过预编译方式和运行期动态代理实现程序功能的统一维护的一种技术.AOP是OOP的延续,是软件 ...
- python文件复制移动shutil模块
shutil.copyfile( src, dst) 从源src复制到dst中去.当然前提是目标地址是具备可写权限.抛出的异常信息为IOException. 如果当前的dst已存在的话就会被覆盖掉 s ...