喵哈哈村的魔法考试 Round #1 (Div.2) ABCD
官方题解:
http://www.cnblogs.com/qscqesze/p/6418555.html#3623453
喵哈哈村的魔法石
传说喵哈哈村有三种神奇的魔法石:第一种魔法石叫做人铁石,拥有A的能量;第二种魔法石叫做地冈石,拥有B的能量;而第三种,则是最神奇的天玄石,拥有无可比拟的C的能量!
但是有一天,沈宝宝太调皮了,把一颗天玄石玩丢了……
“这可玩大发了,这样我会被天行廖责备的。”沈宝宝悲伤的说到,“怎么办呢?”
这时候沈宝宝望了望窗外的飞过的白鸽,突然急中生智,想到了一个办法:干脆就用人铁石和地冈石把天玄石凑出来吧!
“只要我拿若干个人铁石,若干个地冈石,他们的能量之和,恰好加起来等于天玄石所拥有的能量。然后再把这些石头粘在一起,那么由若干个石头的组成的整体,我不就可以看做是一个天玄石了吗?“
沈宝宝愈发觉得自己机智。
所以现在有一个问题摆在你的面前了,给你A,B,C,请判断是否存在两个大于等于0的整数x,y满足Ax+By=C.
第一行一个T,表示有T组测试数据。
接下来T行,每行三个整数a,b,c,分别表示三块石头的能量值。
满足(1<=T<=100,1 ≤ a, b ≤ 100, 1 ≤ c ≤ 10 000)
对每一组测试答案均需要输出结果,如果可行的话,输出Yes,否则输出No
2 1 2 3 4 6 15
Yes No
解法:刚刚开始认为是扩展欧几里得,结果姿势不够不会写,后来发现我们先设定b=0,那么答案x=c/a,然后根据这个x为界限,从0开始寻找有关b的解
1 #include<bits/stdc++.h> 2 using namespace std; 3 int main() 4 { 5 int T; 6 cin >> T; 7 while(T--) 8 { 9 int a,b,c; 10 cin>>a>>b>>c; 11 int y=0; 12 int flag=0; 13 int x=c/a; 14 for(int i=0;i<=x;i++) 15 { 16 if((c-a*i)%b==0) 17 { 18 flag=1; 19 break; 20 } 21 } 22 if(flag) 23 { 24 cout<<"Yes"<<endl; 25 } 26 else 27 { 28 cout<<"No"<<endl; 29 } 30 } 31 return 0; 32 }
喵哈哈村的括号序列
喵哈哈村的括号序列和外界的括号序列实际上是一样的。
众所周知"()"这样的,就是一个标准的括号序列;"()()()()"这样也是括号序列;“((()))()”这样也是一个合法的括号序列。但是"((("这样,就不是一个合法的括号序列了。
现在沈宝宝非常好奇,给你一个字符串,请从中找出最长的合法括号序列出来。
不知道你能找到吗?
第一行一个T,表示有T组数据。
接下来T行,每一行都是一个字符串。
保证字符串的长度小于100000。
而且字符串中保证只会出现"(",")"这两种字符之一。
1<=T<=10
对于每一组测试数据,输出最长的合法括号序列的长度。
2 )((())))(()()) )(
6 0
解法:用栈一定是没错的啦,我们遍历判断括号匹配情况,并记录其位置,如果匹配成功就从栈中删除,否则留下
比如
) ( ( ( ) ) ) ) ( ( ) ( ) )
0 7
最后计算哪段最长就行了
1 #include<bits/stdc++.h> 2 using namespace std; 3 int main() 4 { 5 int T; 6 cin >> T; 7 while(T--) 8 { 9 string a; 10 cin >> a; 11 stack<int> s; 12 s.push(-1); 13 int maxn = -1; 14 for( int i = 0; i < a.length(); i++ ) 15 { 16 if(s.top()==-1) 17 { 18 s.push(i); 19 continue; 20 } 21 else if( a[s.top()] == '(' and a[i] == ')') 22 { 23 s.pop(); 24 } 25 else 26 { 27 s.push(i); 28 } 29 } 30 int tmp; 31 int q = a.length(); 32 while( !s.empty() ) 33 { 34 tmp = s.top(); 35 // cout<<tmp<<endl; 36 s.pop(); 37 maxn = max (abs(tmp-q),maxn); 38 q = tmp; 39 } 40 cout << maxn-1 << endl; 41 } 42 return 0; 43 }
喵哈哈村的魔法石(II)
沈宝宝的天玄石做的又丑又难看,戴尔廖实在是看不下去了,于是就出手帮助了他。
戴尔廖从怀中掏出了很多块神奇的石头,这些石头都是矿石结晶。每颗矿石结晶拥有着A[i]的人之精华,以及B[i]的地之精华。
戴尔廖缓缓道:“传说中,只要你拥有的石头的人之精华的和为SA,你拥有的石头的地之精华的和为SB,且SA除以SB恰好等于C,拿这些石头去配比,就能得到完美的天玄石!”
沈宝宝一听,高兴的跳了起来!
戴尔廖说:“不急不急,这些石头我可不能白白给你,第i颗石头,你需要付出C[i]的代价,我才会给你。”
这时,沈宝宝犯难了,沈宝宝究竟最少需要付出多少的代价,才能配比得到天玄石呢?
第一行一个T,表示有T组测试数据。
接下来每组数据:
第一行为两个整数n和C,表示戴尔廖拥有的矿石结晶个数,以及配比需要的比值C。
接下来n行,每行三个整数,A[i],B[i],C[i],分别表示人之精华、地之精华和购买石头需要的代价。
数据满足:
1<=T<=10
1<=n<=100
1<=A[i],B[i]<=10
1<=c[i]<=10000
1<=C<=100
保证所有数据均为整数。
对于每组数据,输出最少合成天玄石的代价,如果不能合成,输出“ShenBaoBao GG”
2 1 1 1 2 1 3 2 3 2 2 3 1 3 3 1 6
ShenBaoBao GG 5
解法:
dp[i][j][z]中i表示已经考虑了第i种配方,j表示已经配了a的容量,z表示已经配了b的容量,先初始化他们的最大值,dp[0][0][0]=0
dp[i+1][j][z]=min(dp[i][j][z],dp[i+1][j][z]) 没有加i配方进去
dp[i+1][j+a[i]][z+b[i]]=min(dp[i+1][j+a[i]][z+b[i]],dp[i][j][z]+c[i]) 加了配方i进去
#include <bits/stdc++.h> using namespace std; const int maxn = 10000; int a[maxn],b[maxn],c[maxn]; int ans,n,k; int x,y; int Ma,Mb; int cn; int inf=(1<<30); int dp[201][500][500]; int main() { int t; cin>>t; while(t--) { cin>>n>>cn; for(int i=0; i<n; i++) { cin>>a[i]>>b[i]>>c[i]; } for(int i=0; i<=100; i++) { for(int j=0; j<=400; j++) { for(int z=0; z<=400; z++) { dp[i][j][z]=inf; } } } dp[0][0][0]=0; for(int i=0; i<n; i++) { for(int j=0; j<=400; j++) { for(int z=0; z<=400; z++) { if(dp[i][j][z]==inf) continue; dp[i+1][j][z]=min(dp[i][j][z],dp[i+1][j][z]); dp[i+1][j+a[i]][z+b[i]]=min(dp[i+1][j+a[i]][z+b[i]],dp[i][j][z]+c[i]); } } } int Minx=inf; for(int i=1; i<=400; i++) { for(int j=1; j<=400; j++) { if(i%j==0&&i/j==cn) { Minx=min(Minx,dp[n][i][j]); } } } if(Minx==inf) { cout<<"ShenBaoBao GG"<<endl; } else { cout<<Minx<<endl; } } return 0; }
喵哈哈村的赛马比赛
喵哈哈村一年一度的赛马比赛要开始了!
沈宝宝和戴尔廖由于达成了某笔交易,成了好朋友,于是他们相约一起去看赛马比赛。
哦豁,这两个人来早了,赛马比赛并没有开始。
于是他们俩决定出一个题,来打发时间:
假设赛马场上有n只马儿,第i只马儿的起点在第i米的位置,这些马儿都会朝着同一个方向奔跑。
每只马儿的速度都不一样,而且大家都不知道这些马儿的速度是多少。
这些马儿将会驰骋在一个无限长的赛道上面,如果马儿A跑过了马儿B,那么马儿B就会被淘汰出局。
现在问题来了,请问考虑所有的情况,场上最后,期望将会剩下多少匹马儿在驰骋呢?
第一行T,表示一共有T组测试数据。
接下来T行,每一行一个整数n,表示比赛一开始马儿的数量。
保证
1<=n<=1000
1<=T<=1000
对于每组测试数据,输出答案,答案需要保留四位。
2 1 2
1.0000 1.5000
解法:瞎猜(并不是)
证明:算每头马对答案的贡献,不妨设有f(i),考虑一个排列就是他们之间的速度关系,第i头马对答案有贡献当且仅当前面的马速度都比他小,那么方案数就是((i-1)!(n-i)!C(n,i))/(n!),化简之后,就是1/i。
#include <bits/stdc++.h> using namespace std; const int maxn = 10000; int a[maxn],b[maxn],c[maxn]; int ans,n,k; int x,y; int Ma,Mb; int cn; int inf=(1<<30); int dp[101][500][500]; int main() { int t; cin>>t; while(t--) { int n; cin>>n; double sum=0.0; for(int i=1;i<=n;i++) { sum+=(double)1/i; } printf("%.4f\n",sum); } return 0; }