[解题报告]训练日记4:武汉工程大学(WIT)acm新生赛

牛客

新生赛包括热身赛和正式赛 and 正式赛rank7

热身赛比较简单但是有一个题是比较好的 会单独写一篇题解的

正式赛 8/10个 还有两个题待补坑

以下题解只是其中八个题的我比赛时候的代码和思路

B题和J题比较好 会单独写题解的(但愿不鸽)

A

签到题 直接if判断

#include<iostream>
#include<cstdio>
#include<queue>
#include<cstring>
#include<string>
#include<algorithm>
#include<cmath>
#include<vector>
#include<sstream>
using namespace std;
#define PI acos(-1)
#define fin freopen("data.txt","r",stdin);
#define LL long long
#define INF 2147483647
#define eps 1e-7
void read(int &x) {
    
    
    char c = getchar(); x = 0;
    while(c < '0' || c > '9') c = getchar();
    while(c <= '9' && c >= '0') x = x*10+c-48, c = getchar();
}

int T , n , cnt;

int main() {
    
    
	//fin
	read(T);
	while(T--) {
    
    
		scanf("%d",&n);
		if(n==10)
			cnt++;
	}
	if(cnt==0)
		printf("666");
	if(cnt>=6)
		printf("just so so");
	if(cnt>=1&&cnt<=5)
		printf("good");
	return 0;
}

C

稍微有点技巧的bfs吧

如果真的去拿每一个起点去bfs搜索终点然后回溯会T掉的 就考虑优化

不如用终点去广搜起点 这样压进去的点只需要一次bfs就好(一次性把终点都入队)

#include<iostream>
#include<cstdio>
#include<queue>
#include<cstring>
#include<string>
#include<algorithm>
#include<cmath>
#include<vector>
#include<sstream>
using namespace std;
#define PI acos(-1)
#define fin freopen("data.txt","r",stdin);
#define LL long long
#define INF 2147483647
#define eps 1e-7
void read(int &x) {
    
    
    char c = getchar(); x = 0;
    while(c < '0' || c > '9') c = getchar();
    while(c <= '9' && c >= '0') x = x*10+c-48, c = getchar();
}

struct Node {
    
    
	int x , y , t;
};
queue<Node>q;
vector<Node>op;
int n , m , k , map[1005][1005] , t , p , vis[1005][1005] , dx[5] , dy[5] , ans[1005][1005] , qd[1005][1005] , ck[1005][1005];

void init() {
    
    
	dx[1] = -1; dy[1] = 0;
	dx[2] = 1; dy[2] = 0;
	dx[3] = 0; dy[3] = -1;
	dx[4] = 0; dy[4] = 1;
}

int jud(int x , int y) {
    
    
	if(x>=1&&x<=n&&y>=1&&y<=m&&vis[x][y]==0&&!map[x][y])
		return 1;
	return 0;
}

void bfs() {
    
    
	while(!q.empty()) {
    
    
		Node u=q.front() , v;
		q.pop();
		if(qd[u.x][u.y])
			ans[u.x][u.y] = u.t;
		for(int i=1; i<=4; i++) {
    
    
			int mx = u.x+dx[i] , my = u.y+dy[i];
			if(jud(mx , my)) {
    
    
				vis[mx][my] = 1;
				v.x = mx;
				v.y = my;
				v.t = u.t + 1;
				q.push(v);
			}
		}
	}
}

int main() {
    
    
	//fin
	init();
	scanf("%d%d%d",&n,&m,&k);
	for(int i=1; i<=k; i++) {
    
    
		int x , y;
		scanf("%d%d",&x,&y);
		map[x][y] = 1;
	}
	scanf("%d",&t);
	for(int i=1; i<=t; i++) {
    
    
		Node x;
		scanf("%d%d",&x.x,&x.y);
		x.t = 0;
		vis[x.x][x.y] = 1;
		q.push(x);
		ck[x.x][x.y] = 1;
	}
	scanf("%d",&p);
	for(int i=1; i<=p; i++) {
    
    
		Node x;
		scanf("%d%d",&x.x,&x.y);
		qd[x.x][x.y] = 1;
		op.push_back(x);
	}
	bfs();
	for(int i=0; i<op.size(); i++) {
    
    
		if(ans[op[i].x][op[i].y]==0) {
    
    
			if(ck[op[i].x][op[i].y])
				printf("0\n");
			else
				printf("-1\n");
		} else
			printf("%d\n",ans[op[i].x][op[i].y]);
	}
	return 0;
}

D

比较简单吧 sort排序输出最大值呗

然后我就写成了滑动窗口???(单调队列)

下面代码是比较麻烦的考场代码

#include<iostream>
#include<cstdio>
#include<queue>
#include<cstring>
#include<string>
#include<algorithm>
#include<cmath>
#include<vector>
#include<sstream>
using namespace std;
#define PI acos(-1)
#define fin freopen("data.txt","r",stdin);
#define LL long long
#define INF 2147483647
#define eps 1e-7
void read(LL &x) {
    
    
    char c = getchar(); x = 0;
    while(c < '0' || c > '9') c = getchar();
    while(c <= '9' && c >= '0') x = x*10+c-48, c = getchar();
}

LL n , k , num[2000005] , q[2000005] , maxx = -1;

void sol() {
    
    
	int l = 1 , r = 0 , i;
	for(i=0; i<k-1; i++) {
    
    
		while(l<=r&&num[q[r]]<num[i])
			r--;
		r++;
		q[r] = i;
	}
	for(; i<n; i++) {
    
    
		if(q[l]<=i-k)
			l++;
		while(l<=r&&num[q[r]]<num[i])
			r--;
		r++;
		q[r] = i;
		maxx = max(maxx , num[q[l]]);
	}
	printf("%d",maxx);
}

int main()
{
    
    
	//fin
	read(n); read(k);
	for(int i=0; i<n; i++)
		read(num[i]);
    sol();
    return 0;
}

E

也是签到题 直接排序出前k大 再相除就可以

#include<iostream>
#include<cstdio>
#include<queue>
#include<cstring>
#include<string>
#include<algorithm>
#include<cmath>
#include<vector>
#include<sstream>
using namespace std;
#define PI acos(-1)
#define fin freopen("data.txt","r",stdin);
#define LL long long
#define INF 2147483647
#define eps 1e-7
void read(LL &x) {
    
    
    char c = getchar(); x = 0;
    while(c < '0' || c > '9') c = getchar();
    while(c <= '9' && c >= '0') x = x*10+c-48, c = getchar();
}

LL n , k , num[100005] , T;
double sum;

int main() {
    
    
	//fin
	read(T);
	while(T--) {
    
    
		read(n); read(k);
		sum = 0;
		for(int i=1; i<=n; i++)
			read(num[i]);
		sort(num+1 , num+n+1);
		for(int i=n; i>=n-k+1; i--)
			sum += num[i];
		printf("%lf\n",sum/k);		
	}
	return 0;
}

F

很明显的并查集

有一个坑点:判断是否是WOW的时候要特判,而非maxx==minn

#include<iostream>
#include<cstdio>
#include<queue>
#include<cstring>
#include<string>
#include<algorithm>
#include<cmath>
#include<vector>
#include<sstream>
using namespace std;
#define PI acos(-1)
#define fin freopen("data.txt","r",stdin);
#define LL long long
#define INF 2147483647
#define eps 1e-7
void read(LL &x) {
    
    
    char c = getchar(); x = 0;
    while(c < '0' || c > '9') c = getchar();
    while(c <= '9' && c >= '0') x = x*10+c-48, c = getchar();
}

LL n , m , fa[100005] , maxx = -1 , minn = INF , cnt[100005];

LL find(LL x) {
    
    
	if(fa[x]==x)
		return x;
	return fa[x] = find(fa[x]);
}

void merge(LL x , LL y) {
    
    
	LL fx = find(x) , fy = find(y);
    if(fx!=fy)
		fa[fx]=fy;
}

int main() {
    
    
	//fin
	read(n); read(m);
	if(m==0) {
    
    
		printf("0");
		return 0;
	}
	for(int i=1; i<=n; i++)
		fa[i] = i;
	for(int i=1; i<=m; i++) {
    
    
		LL x , y;
		read(x); read(y);
		merge(x , y);
	}
	for(int i=1; i<=n; i++)
		cnt[i] = 1;
	for(int i=1; i<=n; i++) {
    
    
		int x = find(i);
		if(i!=x)
			cnt[x]++;
	}
	for(int i=1; i<=n; i++) {
    
    
		LL x = cnt[find(i)];
		if(!x)
			continue;
		maxx = max(maxx , x);
		minn = min(minn , x);
	}
	if(maxx==minn) {
    
    
		int op = find(1);
		for(int i=2; i<=n; i++)
			if(find(i)!=op) {
    
    
				printf("0");
				return 0;
			}
		printf("WOW");		
	}
	else
		printf("%lld",maxx-minn);
	return 0;
}

G

官方题解好像有简单做法 我的做法就是模拟

(应该不太难 我一次就A了呢)

#include<iostream>
#include<cstdio>
#include<queue>
#include<cstring>
#include<string>
#include<algorithm>
#include<cmath>
#include<vector>
#include<sstream>
using namespace std;
#define PI acos(-1)
#define fin freopen("data.txt","r",stdin);
#define LL long long
#define INF 2147483647
#define eps 1e-7
void read(LL &x) {
    
    
    char c = getchar(); x = 0;
    while(c < '0' || c > '9') c = getchar();
    while(c <= '9' && c >= '0') x = x*10+c-48, c = getchar();
}

LL n , m , map[2005][2005] , x , y , flag , sum1 , sum2 , cnt , cir;

int main() {
    
    
	//fin
	read(n); read(m);
	for(int i=1; i<=n; i++)
		for(int j=1; j<=m; j++)
			read(map[i][j]);
	flag = 1; cir = 0; x = 1;
	while(1) {
    
    
		if(cnt==n*m)
			break;
		if(flag==1) {
    
    
			for(int i=y+1; i<=(m-cir); i++) {
    
    
		//		cout<<map[x][i]<<" ";
				cnt++;
				if(cnt%2==0)
					sum2 += map[x][i];
				else
					sum1 += map[x][i];
			}
			flag = 2;
			y = m-cir;
			continue;
		}
		if(flag==2) {
    
    
			for(int i=x+1; i<=(n-cir); i++) {
    
    
		//		cout<<map[i][y]<<" ";
				cnt++;
				if(cnt%2==0)
					sum2 += map[i][y];
				else
					sum1 += map[i][y];
			}
			flag = 3;
			x = n-cir;
			continue;
		}
		if(flag==3) {
    
    
			for(int i=m-cir-1; i>=(cir+1); i--) {
    
    
			//	cout<<map[x][i]<<" ";
				cnt++;
				if(cnt%2==0)
					sum2 += map[x][i];
				else
					sum1 += map[x][i];
			}
			flag = 4;
			y = cir+1;
			continue;
		}
		if(flag==4) {
    
    
			for(int i=n-cir-1; i>(cir+1); i--) {
    
    
		//		cout<<map[i][y]<<" ";
				cnt++;
				if(cnt%2==0)
					sum2 += map[i][y];
				else
					sum1 += map[i][y];
			}
			flag = 1;
			cir++;
			x = cir+1;
			continue;
		}
	}
	if(sum1==0)
		printf("-1\n");
	else
		printf("%lld\n",sum1);
	if(sum2==0)
		printf("-1\n");
	else
		printf("%lld\n",sum2);
 	return 0;
}

H

读懂题吧(唯一一道英文题面)

根据题目来就行 能否除尽输出的时候特判一下

#include<iostream>
#include<cstdio>
#include<queue>
#include<cstring>
#include<string>
#include<algorithm>
#include<cmath>
#include<vector>
#include<sstream>
using namespace std;
#define PI acos(-1)
#define fin freopen("data.txt","r",stdin);
#define LL long long
#define INF 2147483647
#define eps 1e-7
void read(LL &x) {
    
    
    char c = getchar(); x = 0;
    while(c < '0' || c > '9') c = getchar();
    while(c <= '9' && c >= '0') x = x*10+c-48, c = getchar();
}

LL a , b , c , d , x1 , x2;
char ch;
string s1 , s2;

LL gcd(LL x , LL y) {
    
    
	if(y==0)
		return x;
	return gcd(y , x%y);
}

LL lcm(LL x  , LL y) {
    
    
	return x/gcd(x,y)*y;
}


void sol1(string s) {
    
    
	int top;
	a = 0; b = 0;
	int len =s.size(); 
	for(int i=0; i<len; i++) {
    
    
		if(s[i]=='/') {
    
    
			top = i+1;
			break;
		}
		a = a*10 + (s[i]-'0');
	}
	for(int i=top; i<len; i++)
		b = b*10 + (s[i]-'0');
	//	cout<<s[i]<<endl;
}

void sol2(string s) {
    
    
	int top;
	c = 0; d = 0;
	int len =s.size(); 
	for(int i=0; i<len; i++) {
    
    
		if(s[i]=='/') {
    
    
			top = i+1;
			break;
		}
		c = c*10 + (s[i]-'0');
	}
	for(int i=top; i<len; i++)
		d = d*10 + (s[i]-'0');
	//	cout<<s[i]<<endl;
}

int main() {
    
    
	//fin
	while(cin>>ch>>s1>>s2) {
    
    
		sol1(s1);
		sol2(s2);
		x1 = gcd(a , b);
		x2 = gcd(c , d);
		a /= x1; b /= x1;
		c /= x2; d /= x2;
		if(ch=='G') {
    
    
			LL p = gcd(a , c) , q = lcm(b , d);
			LL o = gcd(p , q);
			p /= o; q /= o;
			if(p%q==0)
				printf("%lld\n",p/q);
			else
				printf("%lld/%lld\n",p,q);				
		}
		if(ch=='L') {
    
    
			LL p = lcm(a , c) , q = gcd(b , d);
			LL o = gcd(p , q);
			p /= o; q /= o;
			if(p%q==0)
				printf("%lld\n",p/q);
			else
				printf("%lld/%lld\n",p,q);				
		}		
	//	cout<<a<<" "<<b<<" "<<c<<" "<<d;			
	//	cout<<endl;
	}
	return 0;
}

I

签到题 根据题目来就行

数据范围不合适的稍微转化一下就好

#include<iostream>
#include<cstdio>
#include<queue>
#include<cstring>
#include<string>
#include<algorithm>
#include<cmath>
#include<vector>
#include<sstream>
using namespace std;
#define PI acos(-1)
#define fin freopen("data.txt","r",stdin);
#define LL long long
#define INF 2147483647
#define eps 1e-7
#define L1 1e7
#define L2 1e8
void read(LL &x) {
    
    
    char c = getchar(); x = 0;
    while(c < '0' || c > '9') c = getchar();
    while(c <= '9' && c >= '0') x = x*10+c-48, c = getchar();
}

LL t , n;
string s;

void sol1() {
    
    
	if(n<=t*L1)
		printf("Safe");
	if(n>t*L1&&n<=t*L2)
		printf("Dangerous");
	if(n>t*L2)
		printf("TLE");
}

void sol2() {
    
    
	if(n<=sqrt(t*L1))
		printf("Safe");
	if(n>sqrt(t*L1)&&n<=sqrt(t*L2))
		printf("Dangerous");
	if(n>sqrt(t*L2))
		printf("TLE");
}

void sol3() {
    
    
	if(n<=pow(t*L1,1.0/3))
		printf("Safe");
	if(n>pow(t*L1,1.0/3)&&n<=pow(t*L2,1.0/3))
		printf("Dangerous");
	if(n>pow(t*L2,1.0/3))
		printf("TLE");
}

void sol4() {
    
    
	n = n*log(n)/log(2);
	if(n<=t*L1)
		printf("Safe");
	if(n>t*L1&&n<=t*L2)
		printf("Dangerous");
	if(n>t*L2)
		printf("TLE");
}

int main() {
    
    
	//fin
	read(t); read(n);
	cin>>s;
	if(s=="n")
		sol1();
	if(s=="n^2")
		sol2();
	if(s=="n^3")
		sol3();
	if(s=="nlogn")
		sol4();
	return 0;
}

rank7是我没想到的 可能的确是因为新生赛吧

签到题比较多 但是还是不够细心不够熟练啊

因为罚时才第7了 还好吧 继续呗

猜你喜欢

转载自blog.csdn.net/cls1277/article/details/109994927