题目大意
在遥远的斯卡布罗集市,有机分子只能由 C , H , O C, H, O C,H,O 三种元素组成。根据珂学家们的探测,一个 C 原子的式量为 13 ,一个 H H H 原子的式量为 1 ,一个 O O O 原子的式量为 17 。一个有机分子的式量恰为各个原子的式量的总和。
对于有机分子式给出如下定义:
有机分子式只可能包含数字、括号和 C , H , O C, H, O C,H,O 三种元素标记;
数字只能出现在元素标记或右括号的右边,代表该元素(或括号内的分子式)重复出现的次数;
数字只可以是不包含前导零的正整数;
如果一个元素右侧没有数字,那么表示该元素只出现一次;
括号内包含非空的有机分子式,但该有机分子式不再嵌套括号。
例如 ( H H ) 3 H ( H ) 、 C O 2 、 C H 12 、 C H H O O (HH)3H(H)、CO2、CH12、CHHOO (HH)3H(H)、CO2、CH12、CHHOO 都是合法的有机分子式。
而 4 H C 4HC 4HC、 C H T H O L L O Y CHTHOLLOY CHTHOLLOY、 C H 3 ( C H 2 ) 3 ( C H ( C H C H 3 ) 2 C H 3 ) 2 ( C H 2 ) 3 C H 3 CH3(CH2)3(CH(CHCH3)2CH3)2(CH2)3CH3 CH3(CH2)3(CH(CHCH3)2CH3)2(CH2)3CH3 都不是合法的有机分子式。
对于符合上述要求的分子式,你能帮助珂学家们计算它的分子式量吗?
输入格式
输入仅一行,包含一个字符串,代表分子式。
保证符合上述定义,字符串中不含除 C , H , O C, H ,O C,H,O,括号和数字以外的字符,且长度不超过 1 0 5 10^5 105 。
输出描述
在一行中输出一个整数,代表该分子的式量。
保证答案不超过 1 0 15 10^{15} 1015。
备注
斯卡布罗集市是一个魔法集市,所以对化学的定义可能和麻瓜世界略有不同。
在第二个样例中,一共出现了 12 个 C C C 和 26 H H H;
在第三个样例中出现了 4 个 C C C、10 个 H H H 和 1 个 O O O。
根据官方题解,这个数据有括号嵌套,用STL中的 s t a c k stack stack 即可,傻逼的我看了题然后按照没有括号嵌套的情况写的只过了 76.9 % 76.9\% 76.9% 的数据。
#include
#include
#include
using namespace std;
typedef long long ll;
string s;
int main()
{
ios::sync_with_stdio(false);cin.tie(0);
cin>>s;
stack<ll>st;
int len=s.size();
for(int i=0;i<len;i++)
{
if(s[i]=='C') st.push(13);
else if(s[i]=='H') st.push(1);
else if(s[i]=='O') st.push(17);
else if(s[i]=='(') st.push(0);
else if(s[i]==')'){
ll t=0;
while(1){
if(!st.empty() && st.top())
t+=st.top(),st.pop();
else{
st.push(t);
break;
}
}
}
else{
ll t=0;
while(s[i+1]>='0'&&s[i+1]<='9')
t=(t+s[i]-'0')*10,i++;
t+=s[i]-'0';
t*=st.top();
st.pop();
st.push(t);
}
}
ll ans=0;
while(!st.empty())
ans+=st.top(),st.pop();
cout<<ans<<endl;
return 0;
}
题目大意
S a b i t Sabit Sabit 爵士是一名高贵的贵族,看遍了人世繁华,他变得热爱异世界文化。
他喜欢在 Q Q QQ QQ 群里和他的小伙伴们聊点二次元文化。可经常他们的话有些偏离二次元,这让 S a b i t Sabit Sabit 很苦恼。
我们认为,假如一句话里含有 2 ,那么这句话很二次元。
同时,群里的二次元浓度由二次元话的数量的占比决定。
现在爵士 S a b i t Sabit Sabit 给你看了一眼群里的聊天记录,希望可以知道群里的二次元浓度是多少。
输入格式
第一行输入一个整数 T ( 1 ≤ T ≤ 100 ) T (1\leq T\leq 100) T(1≤T≤100),表示数据的组数。对于每组数据:
第一行输入一个整数 n ( 1 ≤ n ≤ 200 ) n (1\leq n\leq 200) n(1≤n≤200),表示聊天记录的条数。
接下来 n n n 行每一行输入一个长度不超过 100 100 100 的字符串。保证不包含大写字母、小写字母、数字和空格以外的字符,并且没有连续的空格,行末不含空格
输出格式
对于每组数据,在一行中输出一个数字表示群里的二次元浓度。
如果你的答案的相对或绝对误差小于 1 0 − 4 10^{-4} 10−4
,那么它会被认为是正确的。即如果你的答案是 a a a 而标准答案为 b,那么你的答案将被认为是正确的当且仅当 ∣ a − b ∣ m a x ( 1 , ∣ b ∣ ) ≤ 1 0 − 4 \frac{|a-b|}{max(1,|b|)}\leq 10^{-4} max(1,∣b∣)∣a−b∣≤10−4
#include
#include
#include
#include
using namespace std;
typedef long long ll;
int main()
{
int t,n;
cin>>t;
string s;
while(t--)
{
double cnt=0;
cin>>n;
getchar();
for(int i=0;i<n;i++)
{
getline(cin,s);
int ok=0;
for(int j=0;j<s.size();j++)
if(s[j]=='2') ok=1;
if(ok) cnt++;
}
double t=(double)n;
cout<<setiosflags(ios::fixed)<<setprecision(10)<<cnt/t<<'\n';
}
return 0;
}
签到题,我用了一下 ios::sync_with_false(0) 过后 g e t l i n ( c i n , s ) getlin(cin,s) getlin(cin,s)无法读入空格,玄学orz,知识盲点,下来查查资料。
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
int T = in.nextInt();
for(int t = 0; t < T; t++){
int cnt = 0;
int n = in.nextInt();
in.nextLine();
for(int i = 0; i < n; i++){
StringBuilder s = new StringBuilder().append(in.nextLine());
if(s.indexOf("2") != -1){
cnt++;
}
}
System.out.println(1.0*cnt/n);
}
}
}
题目大意
虚拟存储器作为现代操作系统中存储器管理的一项重要技术,实现了内存扩充功能。但该功能并非是从物理上实际地扩大内存的容量,而是从逻辑上实现对内存容量的扩充,让用户所感觉到的内存容量比实际内存容量大得多。于是便可以让比内存空间更大的程序运行,或者让更多的用户程序并发运行。这样既满足了用户的需要,又改善了系统的性能。
当用户看到自己的程序能在系统中正常运行时,他会认为,该系统所具有的内存容量一定比自己的程序大,或者说,用户所感觉到的内存容量会比实际内存容量大得多。但用户所看到的大容量只是一种错觉,是虚的,故人们把这样的存储器称为虚拟存储器。
在页式虚拟存储系统中,虚拟空间被分成大小相等的页,称为逻辑页或虚页。主存空间也被分成同样大小的页,称为物理页或实页。程序要运行必须存在物理内存中,但虚拟内存比实际物理内存空间到大得多,因此只有一部分页面真正存在物理内存之中,其余页面都还存在外存。
用户编制程序时使用的地址称为虚地址或逻辑地址,其对应的存储空间称为虚存空间或逻辑地址空间;而计算机物理内存的访问地址则称为实地址或物理地址,其对应的存储空间称为物理存储空间或主存空间。程序进行虚地址到实地址转换的过程称为程序的再定位。
当要访问一个逻辑地址时,其对应的页面可能在主存中,也可能不在。如果在,那么就要把虚拟地址转换成为实址,再到物理内存中进行访问。如果不在,就要发出缺页中断。
当前计算机的地址为 32 位二进制表示,按字节编址。虚存大小为 2 n 2^n 2n 字节,物理内存大小为 2 m 2^m 2m 字节,页面大小为 2 p 2^p 2p 字节。
虚拟空间的的地址称为虚拟地址,虚拟地址分为两个字段:高位字段为虚页号,低位字段为页内地址。实存地址也分为两个字段:高位字段为实页号,低位字段为页内地址。同时页面大小都取2的整数幂个字节。
例如 n = 10 , m = 8 , p = 6 n=10 ,m=8,p=6 n=10,m=8,p=6 ,当前物理内存中有 256 字节,每页大小 64 字节,共有4页,虚拟内存大小为 1024 字节,共有 16 页,物理内存第 [0,1,2,3] 页中对应存了虚拟内存的第 [1,11,14,7] 页。
如一个虚拟地址为 00000000000000000000000111010100 ,低 6 位为 010100 为页内地址,高 26 位为 00000000000000000000000111 , 为页号,即为第 7 页。根据上述描述,虚拟内存中的第 7 页存放在主存中的第 3 页,要访问的数据存在主存第 3 页,页内地址为 010100的地方。故物理地址为 00000000000000000000000011010100。如下图所示。
再如一个虚拟地址为 00000000000000000000001000111100 ,低 6 位为 111100 为页内地址,高 26 位为 00000000000000000000001000 , 为页号,即为第 8 页。但根据上述描述,虚拟内存中的第 8 页不在主存中,要访问该地址就会发出缺页中断。
TL;DR: 现给出主存各页面中存的对应的虚存页号,当程序提出要访一个逻辑地址时,请确定该地址所对应的物理地址,或发出中断信号。
输入格式
为了表示简洁,在测试数据中的地址都以 8 位大写十六进制数来表示一个 32 位二进制地址。
第一行输入 3 个十进制整数 n, m, p (0 < p < m ≤ \leq ≤ n ≤ \leq ≤ 32, m − p ≤ m - p\leq m−p≤ 14),分别表示虚拟内存大小为 2 n 2^n 2n 字节,物理内存大小为 2 m 2^m 2m 字节,每页大小为 2 p 2^p 2p 字节。
第二行输入 2 m − p 2^{m-p} 2m−p 个十进制整数 a 0 a_0 a0, a 1 a_1 a1, … a 2 m − p − 1 \ldots a_{2^{m-p} - 1} …a2m−p−1,分别代表当前主存第 i i i 页中存了虚拟内存的第 a i a_i ai 页。
第三行输入一个十进制整数 q q q (1 ≤ \leq ≤ q ≤ \leq ≤ 2333) ,代表询问的数量。
接下来 q q q 行,每行输入一个 8 位十六进制数代表程序要访问的虚拟地址。
输出格式
对于每次询问,在一行输出一个十六进制数代表所对应的物理地址,或输出 interrupt! 代表发出缺页中断。
#include
#include
#include
typedef long long LL;
using namespace std;
int t, n, m, p, q, res[1005];
LL a[1 << 16];
char s[105];
int change(char ch)
{
if(ch >= '0' && ch <= '9') return ch - '0';
return ch - 'A' + 10;
}
int main()
{
scanf("%d %d %d", &n, &m, &p);
int len = 1 << (m - p);
map<LL, LL> mp;
for (int i = 1; i <= len; i++)
scanf("%lld", &a[i]),mp[a[i]] = i;
scanf("%d", &q);
LL x;
while(q--)
{
scanf("%s", s + 1);
x = 0;
LL tmp = 1;
for (int i = 8; i ; i--)
x += tmp * change(s[i]),tmp *= 16; //转换成十进制
LL tmp1 = x >> p; //对应页号
if(mp[tmp1])
{
// x%(1<
LL ans = (x % (1 << p)) + ((mp[tmp1] - 1) << p);
int cnt = 0;
while(ans)
{
res[++cnt] = ans%16;
ans /= 16;
}
for (int i = cnt + 1; i <= 8; i++) res[i] = 0;
for (int i = 8; i; i--)
{
if(res[i] >= 10) printf("%c", res[i] - 10 + 'A');
else printf("%d", res[i]);
}
puts("");
}
else puts("interrupt!");
}
return 0;
}
题目描述
Compute 对于某些特殊的数字有着独特的爱好。例如,有三个正整数 a , b , c a, b, c a,b,c 和某一个目标值 k k k,如果 gcd ( a , b ) = gcd ( b , c ) = gcd ( a , c ) = k \gcd(a,b)=\gcd(b,c)=\gcd(a,c)=k gcd(a,b)=gcd(b,c)=gcd(a,c)=k,并且 a , b , c ≠ k a,b,c \neq k a,b,c=k ,那么他认为这三个数是一组好数。 其中 gcd ( x , y ) \gcd(x,y) gcd(x,y)表示整数 x x x 和 y y y 的最大公约数。当然这不够刺激。现在 C o m p u t e Compute Compute 想要知道,如果已知三个数的和 n n n 和目标值 k k k,是否存在一组 a , b , c a, b, c a,b,c 可以让它们是一组好数。
输入描述
第一行输入一个整数 T ( 1 ≤ T ≤ 1000 ) T (1\leq T \leq 1000) T(1≤T≤1000),表示数据的组数。对于每组数据:仅一行包含两个整数 n , k n, k n,k ( 1 ≤ n , k ≤ 1 0 18 ) 1\leq n,k \leq 10^{18}) 1≤n,k≤1018),分别表示 a , b , c a, b, c a,b,c 的和与目标值。
输出描述
对于每一组数据,在一行输出三个整数,中间以空格分隔,表示找到的一种方案。如果有多种方案,任意输出其中一种即可。
特别地,如果没有满足条件的方案,在一行输出 -1 -1 -1。
输入样例
2
20 2
12 2
输出样例
4 6 10
-1 -1 -1
#include
#include
using namespace std;
typedef long long LL;
const int maxn=1e6+7;
LL prime[maxn],cnt;
bool st[maxn];
void Get_prime()
{
for(int i=2;i<maxn;i++)
{
if(!st[i]) prime[cnt++]=i;
for(int j=0;prime[j]<=maxn/i;j++)
{
st[prime[j]*i]=true;
if(i%prime[j]==0) break;
}
}
}
int main()
{
int t;
Get_prime();
scanf("%d",&t);
while(t--)
{
LL n,k;
scanf(" %lld%lld",&n,&k);
if(n%k)
{
puts("-1 -1 -1");
continue;
}
int ok=0;
n/=k;
for(int a=0;a<cnt;a++)
{
for(int b=a+1;b<cnt;b++)
{
LL c=n-prime[a]-prime[b];
if(c<=1) break;
if(__gcd(c,prime[a])==1&&__gcd(c,prime[b])==1)
{
printf("%lld %lld %lld\n",prime[a]*k,prime[b]*k,c*k);
ok=1;
break;
}
}
if(ok) break;
}
if(!ok) puts("-1 -1 -1");
}
return 0;
}
#include
using namespace std;
typedef long long LL;
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
LL n,k;
scanf("%lld%lld",&n,&k);
if(n%k)
{
puts("-1 -1 -1");
continue;
}
LL nn = n/k;
LL x = 2; if(nn&1) x++; LL y = (nn-x)/2-1; LL z = (nn-x)/2+1;
while((x==y || y==z || x==z || (y%2==0) || (z%2==0) || (z%x==0) || (y%x==0)) && y > 1) y--,z++;
if(y>1 && z>1)
printf("%lld %lld %lld\n",x*k,y*k,z*k);
else puts("-1 -1 -1");
}
return 0;
}
题目描述
S p a r k e n Sparken Sparken 和 C u b e r c s l Cubercsl Cubercsl 喜欢玩游戏。这天他们从 C o m p u t e Compute Compute 那里得到了一棵有 n n n 个点的树(有 n − 1 n-1 n−1 条边的连通图),于是他们决定利用这棵树来进行游戏。游戏规则是这样的:
两个人轮流从树上选择一条边,对这条边两边所连接的点数较少的一边进行"收获’‘操作,并获得相同于所收获的点数的分数。在进行"收获’‘操作之后,对应边的一侧在之后的游戏中不再存在。特别的,如果两边的点数相同,可以任选一边"收获’’。
如果树上只剩下一个点,那么可以单独对这一个点进行"收获’’。
在双方都不能操作时,分数高者获胜。
现在 S p a r k e n Sparken Sparken 一如既往的得到了先手的权利。她想知道,如果他们都按照最优策略进行游戏,她是否能获胜。为了保证两人一定能分出胜负,保证 n n n 为奇数。
输入描述
第一行输入一个整数 T T T ( 1 ≤ T ≤ 1\leq T\leq 1≤T≤ 10),表示数据的组数。对于每组数据:第一行输入一个整数 n n n ( 1 ≤ n ≤ 19 1\leq n \leq 19 1≤n≤19, n n n 为奇数),表示树的点数。
接下来 n − 1 n-1 n−1 行,每行输入两个整数 u u u, v v v ( 1 ≤ u , v ≤ n 1 \leq u, v \leq n 1≤u,v≤n) 表示树的一条边。
输出描述
对于每一组数据,在一行输出一个字符串:如果 S p a r k e n Sparken Sparken 可以获胜,输出 Y e s Yes Yes,否则输出 N o No No。
输入样例
1
3
1 2
1 3
输出样例
Yes
#include
using namespace std;
int main()
{
int t,n;
scanf("%d",&t);
while(t--)
{
int x,y;
scanf("%d",&n);n--;
for(int i=0;i<n;i++) scanf(" %d%d",&x,&y);
puts("Yes");
}
return 0;
}
题目描述
由于一些原因, C u b e r c s l Cubercsl Cubercsl 又送了 C o m p u t e Compute Compute 一个长度为 n 的数组。
但是 C u b e r c s l Cubercsl Cubercsl 的兴趣很奇怪,他要求 C o m p u t e Compute Compute 从中选恰好 ⌊ n 2 ⌋ \lfloor \frac{n}{2} \rfloor ⌊2n⌋ 个才能拿走,并且不能选择在数组中相邻的数。同时, C o m p u t e Compute Compute 也有着奇怪的癖好 — 他一定会选择第 x x x 个数。既然能拿, C o m p u t e Compute Compute 当然想要越多越好。即他想知道,他能拿走的数的和最大是多少。
输入描述
第一行输入两个数 n , x ( 2 ≤ n ≤ 200000 , 1 ≤ x ≤ n ) n,x (2\leq n \leq 200000, 1\leq x \leq n) n,x(2≤n≤200000,1≤x≤n),表示数组的长度和 C o m p u t e Compute Compute 一定会选的数的位置。
第二行输入 n n n 个整数 a 1 , a 2 , … , a n a_1, a_2, \ldots, a_n a1,a2,…,an ( ∣ a i ∣ ≤ 1 0 9 (|a_i|\leq 10^9 (∣ai∣≤109),中间以空格分割。
输出描述
在一行中输出一个整数,表示 C o m p u t e Compute Compute 能拿走的数的和的最大值。
输入样例
6 1
1 2 3 4 5 6
输出样例
11
#include
#include
using namespace std;
typedef long long LL;
const int maxn=2e5+7;
LL a[maxn],res[maxn],dp[maxn];
LL t=1e16;
int main()
{
int n,x;
scanf("%d%d",&n,&x);
for(int i=1;i<=n;i++) scanf("%lld",&a[i]);
a[x]+=t; //最后的答案一定包含给定的项
res[1]=a[1];
for(int i=3;i<=n;i++) res[i]=res[i-2]+a[i]; //奇数项前缀和
for(int i=2;i<=n;i++) //状态转移
{
if(i&1) dp[i]=max(dp[i-1],dp[i-2]+a[i]);
else dp[i]=max(res[i-1],dp[i-2]+a[i]);
}
printf("%lld\n",dp[n]-t);
return 0;
}
题目描述
志摩凛是一个在爷爷的影响下开始露营的独自露营者。露营是一种体验自然的美好享受,但是也难免遭遇困难,特别在一些人工管理不是很充足的露营地更是如此。为了收集露营地的一些信息,往往需要询问一些过来人。
已知露营地可以用一个 n × m n\times m n×m 的矩阵表示,且地图上任意相邻的两个点高度差都恰好为 1 (若两个格点共有一条边则他们相邻),志摩凛想知道每一点的地形高度来保障露营生活的正常展开。她收集了 k k k 条信息,第 i i i 条信息表示 ( x i , y i ) (x_i,y_i) (xi,yi) 处的高度为 h i h_i hi 请你帮她还原出一种符合所有已有信息的地图,或者告诉她已有的信息中一定有一些是错误的。
输入描述
第一行输入两个整数 n , m n, m n,m ( 0 < n × m ≤ 100000 0\lt n\times m \leq 100000 0<n×m≤100000),表示露营地是一个 n × m n\times m n×m 的场地。
第二行输入一个整数 k k k ( 0 ≤ k ≤ 20000 0\leq k\leq 20000 0≤k≤20000),表示收集到的信息。
后面 k k k 行每行输入三个整数 x i , y i , h i x_i,y_i,h_i xi,yi,hi ,( 1 ≤ x i ≤ n 1\leq x_i\leq n 1≤xi≤n, 1 ≤ y i ≤ m 1\leq y_i\leq m 1≤yi≤m, ∣ h i ∣ ≤ 1000 |h_i|\leq 1000 ∣hi∣≤1000),表示坐标为 ( x i , y i ) (x_i,y_i) (xi,yi) 的地点高度为 h i h_i hi
输入数据保证对于 ∀ i ≠ j \forall i\neq j ∀i=j, ( x i , y i ) ≠ ( x j , y j ) (x_i,y_i)\neq(x_j,y_j) (xi,yi)=(xj,yj) 。
输出描述
如果不存在一种合法的方案,在一行输出 N o No No 。
否则在一行输出 Y e s Yes Yes。接下来输出一个 n × m n\times m n×m的矩阵表示露营地各点的高度,并且每个点的高度 ∣ h ∣ ≤ 1 0 9 |h| \leq 10^9 ∣h∣≤109
如果有多种方案,任意输出其中一种即可。
输入样例
3 3
2
1 1 0
2 2 2
输出样例
Yes
0 1 2
1 2 3
2 3 4
#include
#include
#include
#include
#include
using namespace std;
const int maxn=1e5+7;
const int inf=0x3f3f3f3f;
int n,m,k;
vector<vector<int>>vis;
struct node{
int x,y,w;
bool operator<(const node &t)const{
return w<t.w;
}
};
priority_queue<node>q;
int dir[4][2]={0,1,0,-1,1,0,-1,0};
bool inbound(int x,int l,int r)
{
if(x >=l && x<= r) return true;
return false;
}
void bfs()
{
for(int i = 1; i <= n; i++)
for(int j = 1; j <= m; j++)
if(vis[i][j] != inf) q.push(node{i, j, vis[i][j]});
/***
while(!q.empty()){
auto now=q.top();
cout<
while(!q.empty()) {
auto now = q.top(); q.pop();
for(int i = 0; i < 4; i++){
int tx = now.x + dir[i][0], ty = now.y + dir[i][1];
if((inbound(tx, 1, n) && inbound(ty, 1, m))&& vis[tx][ty] == inf) {
// cout<<"tx = "<[ tx][ty] = now.w-1;
q.push(node{tx, ty, vis[tx][ty]});
}
}
}
}
int main()
{
int x,y,z;
scanf(" %d%d%d",&n,&m,&k);
// vector>vis(n+1,vector(m+1,inf));
vis.resize(n+1,vector<int>(m+1,inf));
for(int i = 0; i < k; i++) {
scanf(" %d %d %d",&x,&y,&z);
vis[x][y]=z;
//ans[x][y]=z;
}
/***
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++) cout<
if(!k) vis[1][1] = 0;
bfs();
int ok = 0;
for(int i = 1; i <= n; i++)
for(int j = 1;j <= m; j++)
for(int k = 0;k < 4; k++){
int tx = i + dir[k][0], ty = j + dir[k][1];
if(inbound(tx, 1, n) && inbound(ty, 1, m)&&abs(vis[tx][ty]-vis[i][j])!=1)
ok=1;
}
// cout<<"ok = "<
if(ok) puts("No");
else{
puts("Yes");
for(int i = 1; i <= n; i++)
for(int j = 1; j<= m; j++)
if(j==m) printf("%d\n",vis[i][j]);
else printf("%d ",vis[i][j]);
}
return 0;
}
这个题个人认为和那个距离和高度差奇偶性并没有啥子关系,就是把每个位置的坐标和权值存一下,按照权值从小到大排序
vector局部初始化用 vis.resize(),我就是傻逼,用的那个vector憨憨行为
题目描述
皮卡丘所生活的国家有 n n n 个城市,可以分别用 0 , 1 , … , n − 1 0,1,\ldots,n-1 0,1,…,n−1 表示;一共有 m m m 条单行道连接着这 n n n 个城市。每条单行道 ( u , v ) (u,v) (u,v) 表示生活在城市 u u u 的神奇宝贝可以到达城市 v v v,但生活在城市 v v v 的神奇宝贝不能通过这条单行道到达城市 u u u。
皮卡丘计划了许多旅行方案:每个旅行方案 [ u , v ] [u,v] [u,v] 表示城市 u u u 是出发站,城市 v v v 是终点站。但有些旅行方案存在缺陷,即从出发站出发后无法到达终点站,这样的方案我们称作为不好的 ( B a d ) (Bad) (Bad) 方案,否则称为好的 ( G o o d ) (Good) (Good) 方案。
聪明的你能否帮助皮卡丘判断每一个旅行方案是好是坏呢?
输入描述
第一行输入两个整数 n , m n,m n,m ( 1 ≤ n ≤ 100000 1 \leq n \leq 100000 1≤n≤100000, 0 ≤ m ≤ n + 5000 0 \leq m \leq n + 5000 0≤m≤n+5000),分别表示城市的数量和道路的数量。
接下来输入 m m m 行,每行输入两个整数 u , v ( 0 ≤ u , v < n ) u,v (0 \leq u,v < n) u,v(0≤u,v<n),表示一条单行道 ( u , v ) (u,v) (u,v)。
第 m + 2 m + 2 m+2 行输入一个整数 q q q ( 1 ≤ q ≤ 300000 (1 \leq q \leq 300000 (1≤q≤300000),表示方案的数量。
接下来输入 q q q 行,每行输入两个整数 x , y x, y x,y ( 0 ≤ x , y < n (0 \leq x,y < n (0≤x,y<n),表示一组旅行方案。
输出描述
对于每一种方案,在一行输出 G o o d Good Good 或 B a d Bad Bad 表示这个方案的好坏。
输入样例
11 12
0 1
0 2
1 3
2 4
2 5
3 6
3 7
4 8
4 9
5 10
5 4
8 1
5
0 7
9 1
2 1
5 6
10 8
输出样例
Good
Bad
Good
Good
Bad