北交邀请赛

北京交通大学第十八届大学生程序设计竞赛


由于比赛结束,没办法看题以及交题,所以把赛后打出来的代码暂放在这里(我认为是对的了)


E.Linux

纯字符串代码题,但赛时打了两个小时也没搞出来,代码水平还是差
一开始干了一个小时才把样例过了,提交W,找问题...... 真改不出来,就去看别的题了。
其实我早可以打这个新思路的,有个毛病:有一个思路了就往死里打,打一半觉得这思路不太行了,各种判断啥的,就是不愿意删掉重新打。这导致我至少浪费了一个小时时间。
后来实在不行了,回来把代码全部推翻,重新打一遍新的思路,这次思路很好,十分钟左右就打出来过样例了。

一开始代码
#include<bits/stdc++.h>
using namespace std;

const int N = 505;

int n, cnt;
map<string, int>son[N * 5];
string op, opname;
string name[N];

void str_sort(string s){
	priority_queue<string, vector<string>, greater<string>>q; 
}

signed main(){
	
	scanf("%d", &n);
	while(n--)
	{
		cin>>op;
		cin>>opname;
		string fa;
		bool flag = false, ff = false, cou = false;
		
		int len = opname.length();
		fa = '/';
		for(int i=0; i<len; i++){
			if(opname[i] == '/'){
				
				if(op[0] == 'm')
				{
					if(!flag) ++cnt, flag = true;
					
					for(int j=i+1; j<len; j++){
						if(ff) break;
						if(opname[j] == '/'){
							if(j+1 < len-1){fa = name[cnt];
							name[cnt] = "";}
							else ff = true;
							break;
						}
						name[cnt] += opname[j];
					}
					if(!ff) son[++son[0][fa]][fa] = cnt, cou = true;
//					if(fa[0] == '/')  cout<<son[0][fa];
				}
				
				else
				{
					string s;
					for(int j=i+1; j<len; j++){
						if(opname[j] == '/'){
							if(j+1 < len-1) s = "";
							else ff = true; 
							break;
						}
						s += opname[j];
					}
					if(ff == false){
						continue; 
					}
					if(s != "") fa = s;
					if(son[0][fa] == 0) cout<<"EMPTY";
					
					priority_queue<string, vector<string>, greater<string>>q;
					for(int i=1; i<=son[0][fa]; i++){
						q.push(name[son[i][fa]]);
					}
					
					while(q.size())
					{
						cout<<q.top()<<" ";
						q.pop();
					}
					cout<<"\n";
					ff = false, cou = true;
				}
				
			}
				
		}
		
		if(op[0] == 'l' and cou == false){
			fa = '/';
			if(son[0][fa] == 0) cout<<"EMPTY";
			priority_queue<string, vector<string>, greater<string>>q;
			
			for(int i=1; i<=son[0][fa]; i++){
				q.push(name[son[i][fa]]);
			}
			
			while(q.size())
			{
				cout<<q.top()<<" ";
				q.pop();
			}
			cout<<"\n";
			cou = true;
		}
		if(op[0] == 'm' and cou == false){
			fa = '/';
			son[++son[0][fa]][fa] = cnt;
		}
		
//		cout<<fa<<" "<<name[son[son[0][fa]][fa]]<<" \n";
	}
	
	return 0;
}
新代码还是W
#include<bits/stdc++.h>
using namespace std;

const int N = 505;

int n, cnt = 0;
map<string, int>son[N * 5];

string op, opname;
string name[N];

void print(string fa) 
{
	if(son[0][fa] == 0) {
		cout<<"EMPTY\n";
		return ;
	}
	
	priority_queue<string, vector<string>, greater<string>>q;
	
	for(int i=1; i<=son[0][fa]; i++){
		q.push(name[son[i][fa]]);
	}
	
	while(q.size())
	{
		cout<<q.top()<<" ";
		q.pop();
	}
	
	cout<<"\n";
}

signed main(){
	
	scanf("%d", &n);
	
	while(n--)
	{
		cin>>op;
		cin>>opname;
		string fa = "";
		
		int len = opname.length();
		
		if(op[0] == 'm')
		{
			++cnt; int k = 0;

			for(int i=len-2; i>=0; i--){
				if(opname[i] == '/') {
					k = i; break;
				}
			}	
			
			for(int i=k+1; i<len-1; i++){
				name[cnt] += opname[i];
			}
			
			if(k == 0){
				fa = '/';
				son[++son[0][fa]][fa] = cnt;
				continue;
			}
			
			for(int i=k-1; i>=0; i--)
			{
				if(opname[i] == '/') break;
				fa += opname[i];
			}
			
			son[++son[0][fa]][fa] = cnt;
		}
		
		
		
		else
		{
			if(len == 1){
				fa = '/';
				print(fa);
				continue;
			}
			
			for(int i=len-2; i>=0; i--){
				if(opname[i] == '/') break;
				fa += opname[i];
			}
			
			print(fa);
		}
	}
	
	return 0;
}

没想到不同文件下可能有相同名字目录的情况,后来考虑到了,比赛快结束了,也没什么简单的办法解决,就没再打。
结束之后吃饭回来发现自己离对很近,只要改一点点就可以了...

改之后的
#include<bits/stdc++.h>
using namespace std;

const int N = 505;

int n, cnt = 0;
map<string, int>son[N * 5];
string op, opname;
string name[N];

void print(string fa) 
{
	if(son[0][fa] == 0) {
		cout<<"EMPTY\n";
		return ;
	}
	
	priority_queue<string, vector<string>, greater<string>>q;
	
	for(int i=1; i<=son[0][fa]; i++){
		q.push(name[son[i][fa]]);
	}
	
	while(q.size())
	{
		cout<<q.top()<<" ";
		q.pop();
	}
	
	cout<<"\n";
}

signed main(){
	
	scanf("%d", &n);
	
	while(n--)
	{
		cin>>op;
		cin>>opname;
		string fa = "";
		
		int len = opname.length();
		
		if(op[0] == 'm')
		{
			++cnt; int k = 0;

			for(int i=len-2; i>=0; i--){
				if(opname[i] == '/') {
					k = i; break;
				}
			}	
			
			for(int i=k+1; i<len-1; i++){
				name[cnt] += opname[i];
			}
			
			if(k == 0){
				fa = '/';
				son[++son[0][fa]][fa] = cnt;
				continue;
			}
			
			for(int i=0; i<k; i++)
			{
				if(opname[i] == '/') continue;
				fa += opname[i];
			}
			
			cout<<fa;
			son[++son[0][fa]][fa] = cnt;
		}
		
		
		
		else
		{
			if(len == 1){
				fa = '/';
				print(fa);
				continue;
			}
			
			for(int i=0; i<len; i++){
				if(opname[i] == '/') continue;
				fa += opname[i];
			}
			
			print(fa);
		}
	}
	
	return 0;
}

AC的大佬们可以看看有没有问题,自己造的样例都没啥问题了。


I.Magic Math

这道题给做的嫌弃自己唐了
完全没多想,就想各种办法求出来 $ \sqrt{mn} $, 因为m, n的范围是 $ 10 ^ {18} $, 相乘肯定超 $ long long $了,用 $ int128 $?, 显然 $ sqrt $函数是不能用的。
就想了点

小(丑)妙招
int a1 = sqrt(a), b1 = sqrt(b);
double a2 = (double)sqrt(a) - a1 * 1.0, b2 = (double)sqrt(b) - b1 * 1.0;
int ans1 = a1 * b1;
double ans2 = a2 * b2, ans3 = a1 * 1.0 * b2, ans4 = a2 * b1 * 1.0;
int ans = ans1 + ans2 + ans3 + ans4;

当时还以为很nice,......但接下来怎么办呢?筛法预处理求出所有素数?明显不行啊,既炸内存又超时,

就各种特判,显然W。
#include<bits/stdc++.h>
#define int long long
using namespace std;

const int MAXN = 1e5 + 10;

int T;

signed main(){
	
	pre();
	int a, b;
	scanf("%lld", &T);
	while(T--)
	{
		scanf("%lld%lld", &a, &b);
		
		int a1 = sqrt(a), b1 = sqrt(b);
		double a2 = (double)sqrt(a) - a1 * 1.0, b2 = (double)sqrt(b) - b1 * 1.0;
		int ans1 = a1 * b1;
		double ans2 = a2 * b2, ans3 = a1 * 1.0 * b2, ans4 = a2 * b1 * 1.0;
		int ans = ans1 + ans2 + ans3 + ans4;
		int pp = ans2 + ans3 + ans4;
		
		if(ans == 2){
			printf("YES\n");
			continue;
		}
		
		if(ans % 2 == 0 or ans % 3 == 0 or ans % 5 == 0 or ans % 7 == 0
			or ans % 11 == 0 or ans % 13 == 0 or ans % 17 == 0){
			printf("NO\n");
			continue;
		}
		
		if((a == 2 and b == 3) or (a == 3 and b == 2)){
			printf("YES\n");
			continue;
		}
		
		if(pp < 2){
			printf("NO\n");
			continue;
		}
		
		if(ans == a or ans == b){
			printf("YES\n");
			continue;
		}
		else{
			printf("NO\n");
			continue;
		}
		
	}
	
	return 0;
}

最后实在想不出了,赛后问 丹恒饮月(比赛时听到他AC之后大叫了),发现自己真唐... a, b是两个相邻的素数,且 一定 $ a \le$ $ \sqrt {ab} $ $ \le b $, 那么我只需要在 $ ab \ge (a + 1) ^ 2 $ 的时候输出NO, 否则输出YES就可以了。
从一开始就完全没忘这想......

改后代码
#include<bits/stdc++.h>
#define int long long
using namespace std;

int T;

signed main(){
	
	int a, b;
	scanf("%lld", &T);
	while(T--)
	{
		scanf("%lld%lld", &a, &b);
		
		double an = b * 1.0 / (a + 1), ns = (a + 1) * 1.0 / a;
		
		if(an >= ns) printf("NO\n");
		else printf("YES\n");
	}
	
	return 0;
}
posted @ 2024-04-14 19:46  Aqr_Rn  阅读(55)  评论(0)    收藏  举报