CSP-J 2021 複賽遊記
Day-1
啥也沒幹
晚上看了看洛谷的討論,據說freopen在開啟的最後要加
fclose(stdin);fclose(stdout);
不加也可。不過據說Linux在return 0之前不會自動關閉檔案,在不確定的情況下,就先加上吧。
Day1
T1
8:30開考,8:40就做完第一題了,用的是暴力列舉。
#include<bits/stdc++.h> using namespace std; int n,l,r; int ans=0; int main(){ freopen("candy.in","r",stdin); freopen("candy.out","w",stdout); scanf("%d%d%d",&n,&l,&r); for(int k=l;k<=r;k++){ ans=max(ans,k%n); } cout<<ans<<endl; fclose(stdin); fclose(stdout); return 0; }
後來看題發現R-L可能大於10的9次方,也就是會超時。算了,先不管了,淦T2了。
T2
插入排序,一開始寫了一個大概的程式碼框架,然後發現操作2是輸出數字排序後的位置,於是直接推倒之前的框架重來,使用結構體儲存數字原來的位置和數值,排序後就可以看見原來的位置了。
本來想用氣泡排序,然後發現冒泡太慢,直接用STL的快排。
#include<bits/stdc++.h> #include<string.h> using namespace std; struct NODE{ int n;//數值 int rank;//編號 }; int n,q; const int MAX_N=8000+10; struct NODE a[MAX_N],temp[MAX_N]; bool cmp(NODE A,NODE B){ return A.n<B.n; } void sort(NODE* a,int n){//氣泡排序 for(int i=1;i<=n;i++){ for(int j=1;j<i;j++){ if(a[j].n>a[i].n)swap(a[i],a[j]); } } } int main(){ freopen("sort.in","r",stdin); freopen("sort.out","w",stdout); scanf("%d%d",&n,&q); for(int i=1;i<=n;i++){ scanf("%d",&a[i].n);a[i].rank=i; } while(q--){ int op,x,v; scanf("%d",&op); if(op==1){ scanf("%d%d",&x,&v); a[x].n=v; } else if(op==2){ scanf("%d",&x); memcpy(temp,a,sizeof(a)); sort(temp+1,temp+n+1,cmp); //sort(temp,n); for(int i=1;i<=n;i++){ if(temp[i].rank==x){//排序前的位置是rank printf("%d\n",i);break;//排序後的位置是i } } } } fclose(stdin); fclose(stdout); return 0; }
T3
一開始9:10左右淦完T2,然後專注的淦T3。T3題目很長,我決定分為兩部分寫,先寫Server端再寫Client端。
寫了約15分鐘還沒寫出成果,乾脆先放在一遍,肝T4。
T4
還是一樣,一開始沒有思路,幹到10:00左右,基本框架完成。
剩餘的時間
10:00-10:30左右,首先是淦T1的另一種演算法,因為T1用暴力迴圈R-L次可能超時,目測70分。
使用對拍大概的測了一下,發現我新寫的演算法不知道哪裡出了問題,輸出的數字都是錯誤的,可能連20分都不到,因此果斷放棄,還是使用暴力演算法。
(話說洛谷使用暴力演算法,民間資料可以AC100分)
T2也稍作修改,總體修改後程式碼如上所示,使用考場的樣例試了一下,4個樣例錯了2個(還是1個,我不記得了)
然後專注的淦T3和T4。
T3硬模擬了出來,自以為沒什麼問題然而還是錯誤不斷,考場的樣例錯了不少,而且樣例輸出特別長,根本找不到問題在哪裡。
最終程式碼:
#include<bits/stdc++.h>
using namespace std;
struct NODE{
string type;//表示Server或Client
int i;//伺服器的編號
int a,b,c,d,e;
bool fail;//連線是否失敗
bool operator ==(struct NODE n){
if(type==n.type && a==n.a && b==n.b && c==n.c && d==n.d && e==n.e)return true;
return false;
}
bool connect(struct NODE n){
if(type!=n.type && a==n.a && b==n.b && c==n.c && d==n.d && e==n.e)return true;
return false;
}
bool legal(){
if(a>=0 && a<=255 && b>=0 && b<=255 && c>=0 && c<=255 && d>=0 && d<=255 && e>=0 && e<=65536)return true;
else return false;
}
};
int n;
const int MAX_N=1010;
struct NODE net[MAX_N];
int main(){
freopen("network.in","r",stdin);
freopen("network.out","w",stdout);
scanf("%d",&n);
int temp=1;
for(int i=0;i<n;i++){
cin>>net[i].type;
net[i].a=net[i].b=net[i].c=net[i].d=net[i].e=-1;
scanf("%d.%d.%d.%d:%d",&net[i].a,&net[i].b,&net[i].c,&net[i].d,&net[i].e);
if(net[i].legal()==false){
cout<<"ERR"<<endl;continue;//忽略這條連線
}
if(net[i].type=="Server")net[i].i=temp,temp+=1;
if(net[i].type=="Server"){
int flag=0;
for(int j=0;j<i;j++){
if(net[j]==net[i])flag=1;
}
if(flag==0)net[i].fail=false,cout<<"OK"<<endl;
else net[i].fail=true,cout<<"FAIL"<<endl;
}
else if(net[i].type=="Client"){
int flag=0;
for(int j=0;j<i;j++){
if(net[i].connect(net[j]) && net[i].fail==false){
flag=1;
cout<<net[j].i<<endl;
break;
}
}
if(!flag)cout<<"FAIL"<<endl;
}
//printf("%d.%d.%d.%d:%d",net[i].a,net[i].b,net[i].c,net[i].d,net[i].e);
}
fclose(stdin);
fclose(stdout);
return 0;
}
T4在11:20之前大概就幹完了,中途還去了一次洗手間,就當是放鬆一下。(話說去洗手間就是放鬆的好機會)
思路大體是使用陣列記錄去掉的元素,然後就簡略寫了一下,然後發現第一個樣例怎麼都不對。
#include<bits/stdc++.h>
using namespace std;
int n;
const int MAX_N=2e5+10;
char a[MAX_N],rem[MAX_N],print[MAX_N];
bool check(){
for(int i=0;i<n;i++){
if(rem[i]==false)return false;
}
return true;
}
int main(){
freopen("fruit.in","r",stdin);
freopen("fruit.out","w",stdout);
scanf("%d",&n);
for(int i=0;i<n;i++)scanf("%d",&a[i]);
for(;;){
rem[0]=true;
for(int i=1;i<n;i++){
if(a[i]==-1)continue;//標記為已移除
if(a[i]!=a[i-1])rem[i]=true;//塊的開頭,需要移除
else rem[i]=false;
}
for(int i=0;i<n;i++){
if(rem[i] && !print[i])printf("%d ",i+1),print[i]=true;
}
printf("\n");
for(int i=0;i<n;i++){
if(rem[i])a[i]=-1;//標記為已移除
}
if(check())break;
}
fclose(stdin);
fclose(stdout);
return 0;
}
最終發現題目有這句話:
注意,每次挑完一個果籃後,“塊”可能會發生變化。比如兩個蘋果“塊”之間的唯一桔子被挑走後,兩個蘋果“塊”就變成了一個“塊”。
然後針對這句話做了大量修改,然後發現程式碼越來越亂,測出來的還是錯的,還錯的更加離譜了,就乾脆不加了,放棄了。
後來發現這題洛谷的民間資料只有10分,看來這還是很重要的一個點。
考試結束前30分鐘都沒事幹,基本檢查了一下freopen是否正確,資料夾是否有多餘內容。我甚至發現旁邊有人在玩谷歌瀏覽器的小恐龍遊戲,估計是真的沒事幹了。
順便在桌面寫了個檔案玩玩const和指標,因為實在沒事幹了。考場的環境甚至有python,然而我幾乎不會
由於我座位號1號,於是第一個交檔案走人。於是就這麼結束了。
分數預估:
70+30+20+10=130,估計是要完蛋了。
附:洛谷民間資料結果(第三題尚未完畢)