CF #328
来源:互联网 发布:带着淘宝去异界 微盘 编辑:程序博客网 时间:2024/05/01 09:49
A:每次在一列中遍历所有行即可,从上往下找找第一个能到顶端的”W”,从下往上照找第一个能到底端的“B”,最后比较较小的那个就行。但是注意题目有说“W”的先动,所以如果它们到达目的地的步数一样时,A获胜。
#include<stdio.h>#include<iostream>#include<string>#include<string.h>#include<algorithm>#include<iomanip>#include<vector>#include<time.h>#include<queue>#include<stack>#include<iterator>#include<math.h>#include<stdlib.h>#include<limits.h>#include<map>#include<set>#include<bitset>//#define ONLINE_JUDGE#define eps 1e-8#define INF 0x7fffffff#define FOR(i,a) for((i)=0;i<(a);(i)++)#define MEM(a) (memset((a),0,sizeof(a)))#define sfs(a) scanf("%s",a)#define sf(a) scanf("%d",&a)#define sfI(a) scanf("%I64d",&a)#define pf(a) printf("%d\n",a)#define pfI(a) printf("%I64d\n",a)#define pfs(a) printf("%s\n",a)#define sfd(a,b) scanf("%d%d",&a,&b)#define sft(a,b,num) scanf("%d%d%d",&a,&b,&num)#define for1(i,a,b) for(int i=(a);i<b;i++)#define for2(i,a,b) for(int i=(a);i<=b;i++)#define for3(i,a,b)for(int i=(b);i>=a;i--)#define MEM1(a) memset(a,0,sizeof(a))#define MEM2(a) memset(a,-1,sizeof(a))#define ll long longconst double PI=acos(-1.0);template<class T> T gcd(T a,T b){return b?gcd(b,a%b):a;}template<class T> T lcm(T a,T b){return a/gcd(a,b)*b;}template<class T> inline T Min(T a,T b){return a<b?a:b;}template<class T> inline T Max(T a,T b){return a>b?a:b;}using namespace std;//#pragma comment(linker,"/STACK:1024000000,1024000000")int n,m;#define N 210#define M 100010#define Mod 1000000000#define p(x,y) make_pair(x,y)char mp[10][10];int main(){#ifndef ONLINE_JUDGE freopen("in.txt", "r", stdin);// freopen("out.txt", "w", stdout);#endif while(sfs(mp[0])!=EOF){ for(int i=1;i<8;i++) sfs(mp[i]); int aans = INF; int bans = -1; for(int j=0;j<8;j++){ int x = INF,y = -1; for(int i=0;i<8;i++){ if(mp[i][j] == 'B') break; else if(mp[i][j] == 'W'){ x = i; break; } } for(int i=7;i>=0;i--){ if(mp[i][j] == 'W') break; else if(mp[i][j] == 'B'){ y = i; break; } } aans = Min(aans,x); bans = Max(bans,y); } bans = 7-bans; if(aans <= bans) printf("A\n"); else printf("B\n"); } return 0;}
B:找找规律,发现公式:(n-2)*(n-2)
#include<stdio.h>#include<iostream>#include<string>#include<string.h>#include<algorithm>#include<iomanip>#include<vector>#include<time.h>#include<queue>#include<stack>#include<iterator>#include<math.h>#include<stdlib.h>#include<limits.h>#include<map>#include<set>#include<bitset>//#define ONLINE_JUDGE#define eps 1e-8#define INF 0x7fffffff#define FOR(i,a) for((i)=0;i<(a);(i)++)#define MEM(a) (memset((a),0,sizeof(a)))#define sfs(a) scanf("%s",a)#define sf(a) scanf("%d",&a)#define sfI(a) scanf("%I64d",&a)#define pf(a) printf("%d\n",a)#define pfI(a) printf("%I64d\n",a)#define pfs(a) printf("%s\n",a)#define sfd(a,b) scanf("%d%d",&a,&b)#define sft(a,b,num) scanf("%d%d%d",&a,&b,&num)#define for1(i,a,b) for(int i=(a);i<b;i++)#define for2(i,a,b) for(int i=(a);i<=b;i++)#define for3(i,a,b)for(int i=(b);i>=a;i--)#define MEM1(a) memset(a,0,sizeof(a))#define MEM2(a) memset(a,-1,sizeof(a))#define ll long longconst double PI=acos(-1.0);template<class T> T gcd(T a,T b){return b?gcd(b,a%b):a;}template<class T> T lcm(T a,T b){return a/gcd(a,b)*b;}template<class T> inline T Min(T a,T b){return a<b?a:b;}template<class T> inline T Max(T a,T b){return a>b?a:b;}using namespace std;//#pragma comment(linker,"/STACK:1024000000,1024000000")ll n,m;#define N 210#define M 100010#define Mod 1000000000#define p(x,y) make_pair(x,y)int main(){#ifndef ONLINE_JUDGE freopen("in.txt", "r", stdin);// freopen("out.txt", "w", stdout);#endif while(sfI(n)!=EOF){ pfI((n-2)*(n-2)); } return 0;}
C:感觉这道题目思路不难,符合条件的就是这么几种数字:
1:[1,Min(t,Min(w,b))-1] 比如2,3,那么1就符合条件。
2:[lcm(a,b),lcm(a,b)+Min(w,b)-1],这里的lcm(a,b)代表的是a,b的公倍数,但注意有个特例就是最后一组在t范围内的上述区间,我们要判断t和lcm(a,b)+Min(w,b)-1的大小关系才行。
但是这道题目坑比较多,最明显的就是求公倍数时的技巧,我们不能直接求,因为数据过大,会超范围,解决方法就是用double类型存储求得的公倍数,这样就不会出现超范围的问题了。
#include<stdio.h>#include<iostream>#include<string>#include<string.h>#include<algorithm>#include<iomanip>#include<vector>#include<time.h>#include<queue>#include<stack>#include<iterator>#include<math.h>#include<stdlib.h>#include<limits.h>#include<map>#include<set>#include<bitset>//#define ONLINE_JUDGE#define eps 1e-8#define INF 0x7fffffff#define FOR(i,a) for((i)=0;i<(a);(i)++)#define MEM(a) (memset((a),0,sizeof(a)))#define sfs(a) scanf("%s",a)#define sf(a) scanf("%d",&a)#define sfI(a) scanf("%I64d",&a)#define pf(a) printf("%d\n",a)#define pfI(a) printf("%I64d\n",a)#define pfs(a) printf("%s\n",a)#define sfd(a,b) scanf("%d%d",&a,&b)#define sft(a,b,num) scanf("%d%d%d",&a,&b,&num)#define for1(i,a,b) for(int i=(a);i<b;i++)#define for2(i,a,b) for(int i=(a);i<=b;i++)#define for3(i,a,b)for(int i=(b);i>=a;i--)#define MEM1(a) memset(a,0,sizeof(a))#define MEM2(a) memset(a,-1,sizeof(a))#define ll long longconst double PI=acos(-1.0);template<class T> T gcd(T a,T b){return b?gcd(b,a%b):a;}template<class T> T lcm(T a,T b){return a/gcd(a,b)*b;}template<class T> inline T Min(T a,T b){return a<b?a:b;}template<class T> inline T Max(T a,T b){return a>b?a:b;}using namespace std;//#pragma comment(linker,"/STACK:1024000000,1024000000")int n,m;#define N 210#define M 100010#define Mod 1000000000#define p(x,y) make_pair(x,y)int main(){#ifndef ONLINE_JUDGE freopen("in.txt", "r", stdin);// freopen("out.txt", "w", stdout);#endif ll t,w,b; while(scanf("%I64d%I64d%I64d",&t,&w,&b)!=EOF){ ll res=0; res += Min(t,Min(w,b)-1); //注意点1,注意比较t和Min(w,b)-1的大小 ll ggcd = gcd(w,b); double lm = (double)(w/ggcd)*b; //求公倍数时注意要用double来存储 ll num = (ll)(t/lm); //求得t区间内有几个公倍数区间 if(num>0){ //如果区间数大于0 res += num; res += (num-1)*(Min(w,b)-1); //前num-1个区间 ll maxlcm = (ll)(lm*num); ll tmp = Min(t-maxlcm,Min(w,b)-1); //最后一个区间得判断其和t的大小关系 res += tmp; } ll gd = gcd(res,t); res /= gd; t /= gd; printf("%I64d/%I64d\n",res,t); } return 0;}
D:这是一道自己不太会的,学习了下,感觉也不难。首先,我们将所有要到达的点自己构造一颗最小虚树,使得这颗虚树包含所有我们要到达的点,求得这颗虚树的边长(即所有边的长度+1)edg,和这棵树的直径(即离得最远的两个点的距离)len,最后的答案就是edg*2-len.
求len的方法很简单,就是先用dfs求出一个端点,然后再用一次求出另外一个,它们之间的距离就是树的直径。
求edge的话就是求出这课虚树包含的点的个数,边长就是 点的个数-1。
#include<stdio.h>#include<iostream>#include<string>#include<string.h>#include<algorithm>#include<iomanip>#include<vector>#include<time.h>#include<queue>#include<stack>#include<iterator>#include<math.h>#include<stdlib.h>#include<limits.h>#include<map>#include<set>#include<bitset>//#define ONLINE_JUDGE#define eps 1e-8#define INF 0x7fffffff#define FOR(i,a) for((i)=0;i<(a);(i)++)#define MEM(a) (memset((a),0,sizeof(a)))#define sfs(a) scanf("%s",a)#define sf(a) scanf("%d",&a)#define sfI(a) scanf("%I64d",&a)#define pf(a) printf("%d\n",a)#define pfI(a) printf("%I64d\n",a)#define pfs(a) printf("%s\n",a)#define sfd(a,b) scanf("%d%d",&a,&b)#define sft(a,b,num) scanf("%d%d%d",&a,&b,&num)#define for1(i,a,b) for(int i=(a);i<b;i++)#define for2(i,a,b) for(int i=(a);i<=b;i++)#define for3(i,a,b)for(int i=(b);i>=a;i--)#define MEM1(a) memset(a,0,sizeof(a))#define MEM2(a) memset(a,-1,sizeof(a))#define ll long longconst double PI=acos(-1.0);template<class T> T gcd(T a,T b){return b?gcd(b,a%b):a;}template<class T> T lcm(T a,T b){return a/gcd(a,b)*b;}template<class T> inline T Min(T a,T b){return a<b?a:b;}template<class T> inline T Max(T a,T b){return a>b?a:b;}using namespace std;//#pragma comment(linker,"/STACK:1024000000,1024000000")int n,m;#define N 210#define M 200010#define Mod 1000000000#define p(x,y) make_pair(x,y)vector<int> G[M];int vis[M],vis2[M];int nd1,nd2;int len;int edgnum;void dfs1(int x,int ds,int pre){ //x代表当前节点,ds代表直径,pre代表前导点 if(ds>len && vis[x]){ //直径变大了,且该点是要包含的 len = ds; nd2 = x; } if(ds == len && vis[x] && nd2>x){ //直径一样,但是x的序号比较小(题目要求的就是最小的序号) nd2 = x; } for(int i=0;i<(int)G[x].size();i++){ //遍历 if(G[x][i] == pre) continue; dfs1(G[x][i],ds+1,x); }}int dfs2(int x,int pre){ //将该虚树要包含的点标记起来,vis2[x]如果不为0,那么x就是虚树上的一个点 if(vis[x]) vis2[x]++; for(int i=0;i<(int)G[x].size();i++){ if(G[x][i] == pre) continue; vis2[x] += dfs2(G[x][i],x); } return vis2[x];}void dfs3(int x,int pre){ //统计该虚树中的所有点 if(vis2[x]) edgnum++; for(int i=0;i<(int)G[x].size();i++){ if(G[x][i] == pre) continue; dfs3(G[x][i],x); }}int main(){#ifndef ONLINE_JUDGE freopen("in.txt", "r", stdin);// freopen("out.txt", "w", stdout);#endif while(sfd(n,m)!=EOF){ for(int i=0;i<=n;i++) G[i].clear(); int u,v; for(int i=1;i<n;i++){ sfd(u,v); G[u].push_back(v); G[v].push_back(u); } int x; memset(vis,0,sizeof vis); memset(vis2,0,sizeof vis2); nd1 = INF; for(int i=0;i<m;i++){ sf(x); vis[x]=1; //标记要包含的点 nd1 = Min(nd1,x); } if(m == 1){ //注意特判啊!! printf("%d\n0\n",nd1); continue; } len=-1; dfs1(nd1,0,-1); //先用dfs求出一个树的端点 nd1 = nd2; //nd1为第一个端点 len = -1; edgnum = 0; dfs1(nd1,0,-1); //求出第二个端点,nd2就是 dfs2(nd2,-1); //标记该虚树中的所有点 dfs3(nd2,-1); //统计虚树的点的个数 printf("%d\n",Min(nd1,nd2)); //输出序号较小的 if(edgnum!=1)edgnum--; //如果不只有1个点,那么边长 = 点的个数-1 printf("%d\n",edgnum*2-len); //最后的答案就是边长*2-树的直径 } return 0;}
0 0