武汉工程大学第一届程序设计女生赛解题报告
xzc 2020.3.8
比赛链接:武汉工程大学第一届程序设计女生赛
A. Multiplication (101/861)
分析:
问x平方几次后就会>=n, 按题意模拟即可。签到题。
代码:
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
int main()
{
int T;
LL k,n;
cin>>T;
while(T--)
{
cin>>n>>k;
int ans = 0;
while(k<n)
{
k = k*k;
++ans;
}
cout<<ans<<endl;
}
return 0;
}
B. Spread (28/520)
样例输入:
1
5 2 2
1 3
1 2
4 5
样例输出:
3
分析:
n个人中有m个人确定被感染。他们之中有t对接触。求所有存在感染风险的人数(包括那m个)。
用并查集合并所有直接和间接接触过的人,把n个人分成若干的集合。对每个集合的总人数进行计数。m个已经确认感染的人所在集合的总人数即为答案。注意不要多算。
代码:
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
const int N = 2e5+10;
int pre[N];
void init(int n) //初始化
{
for(int i=0;i<=n;++i) pre[i] = i;
}
int Find(int x)
{
return x==pre[x]?x:pre[x]=Find(pre[x]);
}
void join(int x,int y)
{
if(x>y) swap(x,y);
int fx = Find(x), fy = Find(y);
if(fx!=fy) pre[fy] = fx;
}
int main()
{
int T,n,m,t,x,y,fa;
scanf("%d",&T);
while(T--)
{
scanf("%d%d%d",&n,&m,&t);
vector<int> v;
for(int i=1;i<=m;++i)
{
scanf("%d",&x);
v.push_back(x);
}
init(n);
while(t--)
{
scanf("%d%d",&x,&y);
join(x,y);
}
int ans = 0;
unordered_map<int,int> cnt; //记录集合人数
unordered_map<int,int> mp; //记录集合是否有被确诊的人
for(int i=1;i<=n;++i)
++cnt[Find(i)];
for(int i=0;i<m;++i)
mp[Find(v[i])] = 1;
for(auto xx:mp)
ans += cnt[xx.first];
printf("%d\n",ans);
}
return 0;
}
C. Transport (24/103)
样例输入:
1
3 3
...
.**
...
1 3 1 1 3 3
样例输出:
6
分析:
简单bfs, n行m列的矩阵,星号不能走,点号可以走,问从指挥部到小区再到医院的最短路成。若不可达,输出-1。
我们可以从小区出发,bfs, 记录第一次到指挥部和第一次到医院的步数,相加即为答案。
代码:
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
const int N = 1005;
char a[N][N];
bool vis[N][N];
int n,m;
struct Node{
int x,y,step;
Node(){
}
Node(int xx,int yy,int s):x(xx),y(yy),step(s){
}
}node;
int X1,Y1,X2,Y2,X3,Y3;
int dx[] =