CSP-J 游記


啊,有人就會問我:“i 老師,i 老師,你為什么只寫了J的游記呢?S的游記在哪里啊?”

啊,我就會回答:“沒資格。”


去年考的太渣了,都沒臉寫游記,這回寫一篇罷(

T1

看了一下題,啪一下就慌了啊,很快啊(主要是因為題目有點長,讀了大概 5min 才看懂)。

看懂了之后就覺得:“撕,這不會是個暴力吧?”

於是敲出了一個從 \(l\sim r\) 暴力的算法。

結果發現,誒,為啥第三個附件輸出的是 230 呢???

(我把 233 4567 4657 看成了 233 4567 4567

這個愣是搞了我 5min+,旁邊的人都開始寫 T2 了,還各種慶祝,心態頓時崩了(calm -= 100)。

自己研究了自己代碼很久還沒發現問題,甚至考場上我小聲的說出了:“收錢協會 T1 樣例是不是錯了啊。”

最后發現是我眼瞎 (╥╯^╰╥)

寫了暴力之后發現 \(r-l\) 最大到 \(1e9\),於是敲除了一個從 \(r\sim l\) 枚舉和一個小剪枝的代碼:

#include<iostream>

using namespace std;

int n, l, r;

int main() {
    cin >> n >> l >> r;
    int ans = -1;
    for (int i = r;i >= l;i--) {
        ans = max(ans, i % n);
        if (ans == n - 1) break;
    }
    cout << ans << endl;
    return 0;
}

寫完就覺得:“T1 穩了穩了,保了個2=”

考后就覺得:“T1 危了危了,不一定2=”

T2

一看題目我就又慌了啊,這 CCF 不講武德。考前復習的 dp 不給我考,給我考排序?!

再花了 5min- 讀完了題,瞬間感覺神清氣爽:“這不就是個橙題嗎?分分鍾切好吧。”

再花了 10min 左右寫出了一份時間復雜度爆炸的代碼:

#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;

const int maxn = 8010;

int n, q;
int a[maxn];
int a1[maxn];

int main() {
	cin >> n >> q;
	for (int i = 1;i <= n;i++) {
		cin >> a[i];
	}
	while (q--) {
		int opt;
		cin >> opt;
		if (opt == 1) {
			int x, v;
			cin >> x >> v;
			a[x] = v;
		} else if (opt == 2) {
			int x;
			cin >> x;
			for (int i = 1;i <= n;i++) {
				a1[i] = a[i];
			}
			for (int i = 1;i <= n;i++) {
				for (int j = i;j >= 2;j--) {
					if (a1[j] < a1[j - 1]) {
						swap(a1[j], a1[j - 1]);
						if (x == j) {
							x = j - 1;
						}
						else if (x == j - 1) {
							x = j;
						}
					}
				}
			}
			cout << x << endl;
		}
	}
	return 0;
}

信心滿滿的打開了 sort3.in(還是 sort4.in 記不清了),測了一下大數據。

好家伙,算了 3s+ 才出答案,就離譜。

試圖關掉同步流卡常失敗。

爬回去看題:

誒,題目中 \(14\sim 16\)\(20\sim 22\)\(a_i\)\(v\) 互不相等,可以干 sort 啊!!!

於是寫出了和原來分數一樣的優化代碼:

#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;

const int maxn = 8010;

int n, q;
int a[maxn];
int a1[maxn];

int main() {
	ios::sync_with_stdio(0); cin.tie(0);
	cin >> n >> q;
	for (int i = 1;i <= n;i++) {
		cin >> a[i];
	}
	while (q--) {
		int opt;
		cin >> opt;
		if (opt == 1) {
			int x, v;
			cin >> x >> v;
			a[x] = v;
		} else if (opt == 2) {
			int x;
			cin >> x;
			for (int i = 1;i <= n;i++) {
				a1[i] = a[i];
			}
			if (n > 1500) {
				sort(a1 + 1, a1 + n + 1);
				for (int i = 1;i <= n;i++) {
					if (a1[i] == x) {
						cout << i << endl;
						break;
					}
				}
			} else {
				for (int i = 1;i <= n;i++) {
					for (int j = i;j >= 2;j--) {
						if (a1[j] < a1[j - 1]) {
							swap(a1[j], a1[j - 1]);
							if (x == j) {
								x = j - 1;
							}
							else if (x == j - 1) {
								x = j;
							}
						}
					}
				}
				cout << x << endl;
			}
		}
	}
	return 0;
}

現在不僅只有 AC 和 TLE 了,還有 RE。


Upd: 2021.10.28

好家伙,竟然可以直接 \(\mathcal{O}(n)\) 枚舉一下比 \(a_x\) 的值小的元素個數就是 opt = 2 的答案了!

時間復雜度直接降到了 \(\mathcal{O}(nq)\)。。。

硬生生被題目給誤導住了,以為就是得用排序才能解決的,結果幾個 for 就給解決了。。。

#include<iostream>
using namespace std;

const int maxn = 8010;
int n, q;
int a[maxn];

int main() {
    cin >> n >> q;
    for (int i = 1;i <= n;i++) {
        cin >> a[i];
    }
    while (q--) {
        int opt;
        cin >> opt;
        if (opt == 1) {
            int x, v;
            cin >> x >> v;
            a[x] = v;
        }
        if (opt == 2) {
            int x;
            cin >> x;
            int val = a[x];
            int ans = 1;
            for (int i = 1;i < x;i++) {
                if (a[i] <= val) {
                    ans++;
                }
            }
            for (int i = x + 1;i <= n;i++) {
                if (a[i] < val) {
                    ans++;
                }
            }
            cout << ans << endl;
        }
    }
    return 0;
}

誒,也不對啊。\(n\times q=8000\times 2\times10^5=1600000000=\text{十六億}\)

爆了吧,按理來說是錯誤的,但是洛谷數據點竟然全過了,有一個點卡了 900ms+ 過的(

CCF 的數據肯定更水,痛失 48pts,要不然我就穩 1= 了 /kk

T3

一看題,哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈或或或或或!哦,我親愛的大模擬!幸好我考前寫了 UVA12412,穩了這波,T3 都能 A,保 1= 了。

賽后發現原來就是個萌萌小模擬,考場上想復雜了

花了將近 10min 讀完題,20min+ 調完第一份代碼。

測一下第一個樣例,Pass。

測一下第二個樣例,WA。Σ( ° △ °|||)

Debug 了 10min,沒找到問題,決定重構(吸取了模擬賽的經驗,新建了個文件重寫,不覆蓋原文件)。

吼吼吼,寫出了第二份代碼。

測了一下第一個樣例,Pass。

測了一下第二個樣例,Pass!!!

測了一下第三個樣例,WA!!!( ╯-_-)╯┴—┴

使用了一下 Linux 自帶的 diff 對拍一下,有區別的行都會顯示出來(別人的對拍程序都太麻煩了)。

發現自己判斷 IP 地址是否正確寫掛了(就是應該輸出 ERR 的時候卻輸出了 OK)。

調了一下就只剩下第 900 多行有一處不相同,結果是忘了開 long long(

改了一下竟然寫出了 AC 代碼。

考場上懶得算時間復雜度了,估計爆炸(但是考慮到這種專注於考模擬的題不會特別在意效率吧),沒管。

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;

#define int long long

int strtoi(string str) {
	int ret = 0;
	for (int i = 0;i < (int)str.size();i++) {
		ret *= 10;
		ret += (str[i] - '0');
	}
	return ret;
}

int cnt = 0;
struct computer {
	string a, b, c, d, e;
	int ia, ib, ic, id, ie;
	int type; //1: Server 0: Client
	bool operator == (const computer& x) const{
		if (x.a == a && x.b == b && x.c == c && x.d == d && x.e == e) {
			return true;
		} else {
			return false;
		}
	}
	void clear() {
		a = b = c = d = e = "";
		ia = ib = ic = id = ie = 0;
		type = 0;
	}
} info[1010];

int readret = -1;
void read() {
	readret = -1;
	string opt;
	cin >> opt;
	if (opt == "Server") info[++cnt].type = 1;
	else info[++cnt].type = 0;
	string str, a, b, c, d, e;
	int pt = 0;
	cin >> str;
	int amt1 = 0, amt2 = 0;
	for (int i = 0;i < (int)str.size();i++) {
		if (str[i] == '.') {
			if (amt2 != 0) {
				readret = 0;
				return;
			}
			amt1++;
		}
		if (str[i] == ':') {
			if (amt1 != 3) {
				readret = 0;
				return;
			}
			amt2++;
		}
		if (str[i] == '.' || str[i] == ':') {
			pt++;
		} else {
			if (pt == 0) a += str[i];
			if (pt == 1) b += str[i];
			if (pt == 2) c += str[i];
			if (pt == 3) d += str[i];
			if (pt == 4) e += str[i];
		}
	}
	if (amt1 != 3 || amt2 != 1) readret = 0;
	if ((strtoi(a) == 0 && a != "0") || (strtoi(b) == 0 && b != "0") || (strtoi(c) == 0 && c != "0") || (strtoi(d) == 0 && d != "0") || (strtoi(e) == 0 && e != "0")) {
		readret = 0;
		return;
	}
	info[cnt].a = a, info[cnt].ia = strtoi(a);
	info[cnt].b = b, info[cnt].ib = strtoi(b);
	info[cnt].c = c, info[cnt].ic = strtoi(c);
	info[cnt].d = d, info[cnt].id = strtoi(d);
	info[cnt].e = e, info[cnt].ie = strtoi(e);
	if (strtoi(a) != 0 && a[0] == '0') {
		readret = 0;
		return;
	}
	if (strtoi(b) != 0 && b[0] == '0') {
		readret = 0;
		return;
	}
	if (strtoi(c) != 0 && c[0] == '0') {
		readret = 0;
		return;
	}
	if (strtoi(d) != 0 && d[0] == '0') {
		readret = 0;
		return;
	}
	if (strtoi(e) != 0 && e[0] == '0') {
		readret = 0;
		return;
	}
	return;
}

signed main() {
	freopen("network.in", "r", stdin);
	freopen("network.out", "w", stdout);
	ios::sync_with_stdio(0); cin.tie(0);
	int n;
	cin >> n;
	while (n--) {
		read();
		if (info[cnt].ia > 255 || info[cnt].ib > 255 || info[cnt].ic > 255 || info[cnt].id > 255 || info[cnt].ie > 65535 || readret == 0) {
			cout << "ERR" << endl;
			info[cnt].clear();
			continue;
		}
		if (info[cnt].type == 1) {
			bool flag = true;
			for (int i = 1;i < cnt;i++) {
				if (info[i] == info[cnt] && info[i].type == 1) {
					cout << "FAIL" << endl;
					info[cnt].clear();
					flag = false;
					break;
				}
			}
			if (flag) cout << "OK" << endl;
		} else {
			bool flag = true;
			for (int i = 1;i <= cnt;i++) {
				if (info[i].type == 1 && info[i] == info[cnt]) {
					cout << i << endl;
					flag = false;
					break;
				}
			}
			if (flag) cout << "FAIL" << endl;
		}
	}
	return 0;
}

T4

沒看。


總結:

離譜的很,頭回 T1 都穩不了。退了吧。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM