北交邀请赛
北京交通大学第十八届大学生程序设计竞赛
由于比赛结束,没办法看题以及交题,所以把赛后打出来的代码暂放在这里(我认为是对的了)
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;
}

浙公网安备 33010602011771号