生活随笔
收集整理的這篇文章主要介紹了
河南省第十三届ICPC大学生程序设计竞赛 【部分题题解】
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
比賽參加了,打的很垃圾。
霸爺說過:一個人要不是比別人大幾個數量級,其實是很難比別人強的。
努力變強,到達巔峰。
目錄
- A: 祝融傳火
- E: Dance with a stick
- F: 圖像識別
- H: 焦糖布丁 【博弈論 nim】
- I: 七便士
- J: 甜甜圈 【模擬TLE做法 正解不會】
- L: 手動計算
- M: 輸入輸出
A: 祝融傳火
https://ac.nowcoder.com/acm/contest/17148/A
名字很厲害,題目講的也很厲害,結果就是一個簽到題。
暴力枚舉,看4個頂點的數是不是相等即可。
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<string>
#include<cstring>
#include<vector>
#include<map>
#include<queue>
using namespace std
;
typedef long long int LL
;
const int N
=1e3+10;
int n
,m
;
int a
[N
][N
];
int main(void)
{ cin
>>n
>>m
;for(int i
=0;i
<n
;i
++){for(int j
=0;j
<m
;j
++)cin
>>a
[i
][j
];}int h
,w
; cin
>>h
>>w
;bool flag
=false;for(int i
=0;i
<n
;i
++){for(int j
=0;j
<m
;j
++){int x
=i
+h
-1;int y
=j
+w
-1;if(x
>=n
||y
>=m
) continue;if(a
[i
][j
]==a
[x
][j
]&&a
[i
][j
]==a
[i
][y
]&&a
[i
][j
]==a
[x
][y
]){flag
=true;break;}}if(flag
) break;}if(flag
) cout
<<"YES"<<endl
;else cout
<<"NO"<<endl
;return 0;
}
E: Dance with a stick
https://ac.nowcoder.com/acm/contest/17148/E
官方題解:
這道題居然是某一年的IMO的題,是一個大風車的問題。大風車證明視頻講解
答案上其實說的也是很清楚了就是說,我們總的數是奇數,這樣選一個中點才可以正好的對半分,每次移動。
左右兩邊的點的數量是不變的。關鍵的問題在于方向向量如何確認。為何是(-1,1e9)。
以下是我的觀點(不一定百分百正確):
當然這里的點的的數量太少了,那么如果點的數量太多的話,我們得這樣。
那么題目給的范圍是[-1e9,1e9] 那么斜率最小就是-1e9 即 y=-1e9x
當x=-1 即 y=1e9 。這就是題解給的答案。(題目說了結果是整數)
如果x=1 y=-1e9 可不可以呢? 答案是肯定的。
#include<cstdio>
#include<iostream>
#include<map>
#include<algorithm>
using namespace std
;
vector
< pair
<int,int> > ve
;
int main(void)
{int n
; cin
>>n
;for(int i
=0;i
<n
;i
++){int x
,y
; cin
>>x
>>y
;ve
.push_back({x
,y
});}sort(ve
.begin(),ve
.end());if(ve
.size()%2==0) {cout
<<"No"<<endl
;return 0;}cout
<<"Yes"<<endl
;int ansx
=ve
[n
>>1].first
,ansy
=ve
[n
>>1].second
;printf("%d %d %d %d\n",ansx
,ansy
,-1,1e9);return 0;
}
F: 圖像識別
https://ac.nowcoder.com/acm/contest/17148/F
找原點,找目標點。
原點有以下幾種情況:
即原點在四個角或者,中間處。
自己的垃圾做法:
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<string>
#include<cstring>
#include<vector>
#include<map>
#include<queue>
using namespace std
;
typedef long long int LL
;
const int N
=1e3+10;
char a
[N
][N
];
int n
,m
;
int x
,y
;
int xx
,yy
;
int dfs(int x
,int y
)
{int dx
[4]={-1,0,1,0};int dy
[4]={0,1,0,-1};int sum
=0;for(int i
=0;i
<4;i
++){int tempx
=x
+dx
[i
];int tempy
=y
+dy
[i
];if(tempx
>=1&&tempx
<=n
&&tempy
>=1&&tempy
<=m
&&a
[tempx
][tempy
]=='*') sum
++;}return sum
;
}
int main(void)
{ cin
>>n
>>m
;for(int i
=1;i
<=n
;i
++){for(int j
=1;j
<=m
;j
++){cin
>>a
[i
][j
];if(a
[i
][j
]=='#') x
=i
,y
=j
;}}bool flag
=false;if(a
[1][1]='*'&&a
[1][2]=='*'&&a
[2][1]=='*') xx
=1,yy
=1,flag
=true;if(a
[1][m
]='*'&&a
[1][m
-1]=='*'&&a
[2][m
]=='*') xx
=1,yy
=m
,flag
=true;if(a
[n
][1]='*'&&a
[n
-1][1]=='*'&&a
[n
][2]=='*') xx
=n
,yy
=1,flag
=true;if(a
[n
][m
]='*'&&a
[n
][m
-1]=='*'&&a
[n
-1][m
]=='*') xx
=n
,yy
=m
,flag
=true;if(!flag
){for(int i
=1;i
<=n
;i
++){for(int j
=1;j
<=m
;j
++){if(a
[i
][j
]=='*'){int t
=dfs(i
,j
);if(t
>=3){xx
=i
,yy
=j
;flag
=true;break;}}}if(flag
) break;}}cout
<<y
-yy
<<" "<<xx
-x
<<endl
;return 0;
}
故優化為:
#include<bits/stdc++.h>
using namespace std
;
int main(){int n
,m
,a
,b
,x
,y
;scanf("%d%d",&n
,&m
);char c
;for(int i
=1;i
<=n
;i
++){for(int j
=1;j
<=m
;j
++){cin
>>c
;if(c
=='#'){a
=i
;b
=j
;}if(j
==1&&c
=='*')y
=i
;if(i
==1&&c
=='*')x
=j
;}}printf("%d %d",b
-x
,y
-a
);
}
H: 焦糖布丁 【博弈論 nim】
https://ac.nowcoder.com/acm/contest/17148/H
不會寫,可以看出是一個nim游戲,但是不會搞,線性基不會。
大佬代碼:https://ac.nowcoder.com/acm/contest/view-submission?submissionId=47917810
#include<bits/stdc++.h>
#define ll long long
using namespace std
;
ll a
[65],b
[65];
ll
add(ll x
)
{ll flag
=0;for(ll i
=60;i
>=0;--i
){if(x
&(1ll<<i
)){if(b
[i
]) x
^=b
[i
];else {b
[i
]=x
;flag
=1;break;}}}return flag
;
}
int main()
{ll t
,n
;cin
>>t
;while(t
--){cin
>>n
;for(ll i
=1;i
<=n
;++i
) cin
>>a
[i
];ll flag
=0;for(ll i
=1;i
<=n
;++i
){if(!add(a
[i
])) {cout
<<"Yes"<<endl
;flag
=1;break;}}if(!flag
) cout
<<"No"<<endl
;for(ll i
=0;i
<=60;++i
) b
[i
]=0;}return 0;
}
I: 七便士
https://ac.nowcoder.com/acm/contest/17148/I
爆搜即可
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<string>
#include<cstring>
#include<vector>
#include<map>
#include<queue>
using namespace std
;
typedef long long int LL
;
bool st
[15];
bool flag
=false;
int k
=0;
void dfs(int index
)
{if(index
==k
){int ans
=0;for(int i
=1;i
<=8;i
++){if(st
[i
]) ans
++;}if(ans
==7) flag
=true;return;}for(int i
=1;i
<=8;i
++){if(!st
[i
]){if(!st
[(i
+2)%8+1]){st
[(i
+2)%8+1]=true;dfs(index
+1);st
[(i
+2)%8+1]=false; }if(!st
[(i
+4)%8+1]){st
[(i
+4)%8+1]=true;dfs(index
+1);st
[(i
+4)%8+1]=false; }}}
}
int main(void)
{ int t
; cin
>>t
;while(t
--){char s
[15]; cin
>>s
+1;memset(st
,0,sizeof st
);k
=0;flag
=false;for(int i
=1;i
<=8;i
++){if(s
[i
]=='1') st
[i
]=true;else k
++;}dfs(1);if(flag
) cout
<<"Yes"<<endl
;else cout
<<"No"<<endl
;}return 0;
}
J: 甜甜圈 【模擬TLE做法 正解不會】
https://ac.nowcoder.com/acm/contest/17148/J
正解是用線段樹或樹狀數組等來完成加速,但是我沒學,據說就是一個板子題。
#include<cstdio>
#include<iostream>
#include<stack>
#include<map>
#include<vector>
#include<algorithm>
using namespace std
;
int n
,m
;
stack
<int>s1
,s2
;
map
<int,int>mp
;
vector
<int> ve
;
long long int ans
=0;
int main(void)
{cin
>>n
>>m
;for(int i
=1;i
<=n
;i
++){int x
; scanf("%d",&x
);mp
[x
]=1;ve
.push_back(x
);}for(int i
=ve
.size()-1;i
>=0;i
--) s1
.push(ve
[i
]);for(int i
=1;i
<=m
;i
++){int x
; scanf("%d",&x
);mp
[x
]=2;ve
.push_back(x
);}for(int i
=ve
.size()-1;i
>=n
;i
--) s2
.push(ve
[i
]);sort(ve
.begin(),ve
.end());while(s1
.size()||s2
.size()){int temp
=ve
[ve
.size()-1]; ve
.pop_back();int k
=mp
[temp
];if(k
==1){while(1){int w
=s1
.top(); s1
.pop();if(w
==temp
) break;ans
++;mp
[w
]=2;s2
.push(w
);}}if(k
==2){while(1){int w
=s2
.top(); s2
.pop();if(w
==temp
) break;ans
++;mp
[w
]=1;s1
.push(w
);}}}cout
<<ans
<<endl
;return 0;
}
L: 手動計算
https://ac.nowcoder.com/acm/contest/17148/L
這道題我是用那個點到橢圓焦點的距離和小于等于2a來判斷是不是在橢圓內,這種方法精度有點丟失,多枚舉些點會超時。
樣例都過了就是AC不了太難受了。
官方題解是這樣的:
#include<cstdio>
#include<iostream>
#include<algorithm>
using namespace std
;
int main(void)
{int t
; cin
>>t
;while(t
--){double a
,b
,c
,d
; cin
>>a
>>b
>>c
>>d
;int ans
=0;for(double i
=-8;i
<=8;i
=i
+0.01){for(double j
=-8;j
<=8;j
=j
+0.01){double s1
=i
*i
/a
/a
+j
*j
/b
/b
;double s2
=i
*i
/c
/c
+j
*j
/d
/d
;if(s1
<=1||s2
<=1) ans
++; }}printf("%.1lf\n",(double)ans
/1600/1600*16*16);}return 0;
}
M: 輸入輸出
https://ac.nowcoder.com/acm/contest/17148/M
這道題巨水,題目我覺得很坑,比賽的時候很多人都做出來了我們隊想了好久才AC。
我當時很懵逼,以為這是一個貪心的題目,類似于區間合并,找一個最優的方法。
題目有一個特別關鍵的字眼就是一定是有解的。
故只需選你要染色的點即可。
故最小代價就是各個區間的距離之和。那個點的限制就是一個煙霧彈。
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<string>
#include<cstring>
#include<vector>
#include<map>
#include<queue>
using namespace std
;
typedef long long int LL
;
const int N
=1e3+10;
char a
[N
];
int main(void)
{ int n
,m
,k
; cin
>>n
>>m
>>k
;long long int ans
=0;for(int i
=0;i
<m
;i
++){int x
,y
; cin
>>x
>>y
;ans
+=abs(x
-y
);} int x
;for(int i
=0;i
<k
;i
++) cin
>>x
;cout
<<ans
<<endl
;return 0;
}
總結
以上是生活随笔為你收集整理的河南省第十三届ICPC大学生程序设计竞赛 【部分题题解】的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。