A. PawnChess
很简单的暴力。
#include<iostream> #include<cstdio> #include<cstdlib> #include<cstring> #include<string> #include<cmath> #include<map> #include<set> #include<list> #include<deque> #include<vector> #include<algorithm> #include<stack> #include<queue> #include<cctype> #include<sstream> using namespace std; #define pii pair<int,int> #define LL long long int const double eps=1e-10; const int INF=1000000000; const int maxn=1000000+10; char mp[10][10]; int main() { //freopen("in2.txt","r",stdin); //freopen("out.txt","w",stdout); for(int i=0;i<8;i++) { scanf("%s",mp[i]); } int sa=INF,sb=INF; for(int i=0;i<8;i++) { for(int j=0;j<8;j++) { if(mp[i][j]==‘W‘) { int st=0; bool can=1; for(int k=i-1;k>=0;k--) { if(mp[k][j]==‘.‘) { st++; } else { can=0; break; } } if(can==1) { sa=min(sa,st); } } else if(mp[i][j]==‘B‘) { int st=0; bool can=1; for(int k=i+1;k<8;k++) { if(mp[k][j]==‘.‘) { st++; } else { can=0;break; } } if(can==1) { sb=min(sb,st); } } } } if(sa>sb) cout<<‘B‘<<endl; else cout<<‘A‘<<endl; //fclose(stdin); //fclose(stdout); return 0; }
B. The Monster and the Squirrel
就是个找规律而已,输入n,输出(n-2)*(n-2)。注意要用long long。
#include<iostream> #include<cstdio> #include<cstdlib> #include<cstring> #include<string> #include<cmath> #include<map> #include<set> #include<list> #include<deque> #include<vector> #include<algorithm> #include<stack> #include<queue> #include<cctype> #include<sstream> using namespace std; #define pii pair<int,int> #define LL long long int const double eps=1e-10; const int INF=1000000000; const int maxn=1000000+10; int main() { //freopen("in2.txt","r",stdin); //freopen("out.txt","w",stdout); LL n; cin>>n; cout<<(n-2)*(n-2)<<endl; //fclose(stdin); //fclose(stdout); return 0; }
C. The Big Race
题目描述太烂,读了半天都不懂。。不做了。。
D. Super M(虚树,找直径)
1.第一次肯定要落在被攻击的点上。因为如果落在无关点上,那么肯定要先从无关点上走到一个攻击点上,那么这段路没有意义啊,完全可以直接落在那个攻击点上。
2.无关的点能不走就不走,所以最后走过的肯定就是一棵包含所有攻击点的最小子树。
3.从一个攻击点出发,最后再回来。总路程是子树的边长之和的2倍。但是实际上到了最后一个攻击点后就没有必要再走回来了,所以最后总路程是sum-mx,但是要使总路程最短,就要让mx(也就是终点到起点的路径长)最长,那么显然是这个虚树的直径最长。
所以本题就是,找出这个虚树,再求出虚树直径。
#include<iostream> #include<cstdio> #include<cstdlib> #include<cstring> #include<string> #include<cmath> #include<map> #include<set> #include<list> #include<deque> #include<vector> #include<algorithm> #include<stack> #include<queue> #include<cctype> #include<sstream> using namespace std; #define pii pair<int,int> #define LL long long int const double eps=1e-10; const int INF=1000000000; const int maxn=1000000+10; const int MAX = 130000; vector<int> adj[MAX]; int d[MAX], size[MAX]; bool mark[MAX]; void dfs(int p, int v) { size[v] = 0; if (mark[v]) size[v] = 1; for (int i = 0; i < adj[v].size(); i++) { int u = adj[v][i]; if (u != p) { d[u] = d[v] + 1; dfs(v, u); size[v] += size[u];//size是子树里有多少mark节点(包括自己) } } } int main() { //freopen("in2.txt","r",stdin); int n, m; cin >> n >> m; for (int i = 0; i < n - 1; i++) { int u, v; cin >> u >> v; u--; v--; adj[u].push_back(v); adj[v].push_back(u); } for (int i = 0; i < m; i++) { int v; cin >> v; v--; mark[v] = true; } dfs(-1, 0); int v = -1; for (int i = 0; i < n; i++) if (mark[i] && (v == -1 || d[v] < d[i])) v = i; memset(d, 0, sizeof(d)); dfs(-1, v); int sum = 0; int mx = 0; for (int i = 0; i < n; i++) { if (size[i] > 0 && m - size[i] > 0)//m==size[i]的那个不用加了,因为边比点少一个。 sum += 2; cout<<i<<‘ ‘<<size[i]<<endl; if (mark[i]) mx = max(mx, d[i]); } for (int i = 0; i < n; i++)//找出字典序小的那个作为登陆点 if (mark[i] && i < v && d[i] == mx) { v = i; break; } cout << v + 1 << "\n" << sum - mx << "\n"; return 0; }
时间: 2024-10-12 15:50:35