比賽中只A了四道...
E題由於不熟悉set和multiset操作導致花了整個下半場調試都始終無法拯救WA的一個點,賽後發現是multiset的erase操作如果是erase某個值就會將multiset中所有這個值都erase掉而非只刪掉1個......這回慘痛的教訓也該刻骨銘心了QAQ......
F題暴力建邊(邊長爲1-k)居然幾十毫秒就能A,比按題解寫的快了整整30倍......不過題解給的思路還是相當值得學習,每走一步如果方向不變則消耗1/k,轉向時則把距離向上取整,可以避免去討論走1/k還是1/(k-1)還是1/(k-2)等等。不過很坑的一點是--有兩組數據卡了向上取整的精度......於是只能整體放大k倍,把同向消耗視作1,轉向則向上加到最近的一個k的倍數,最終答案再除以k......
吐槽一句......正解本來就不容易想到,數據還要卡他一下,這怕是鼓勵大家都暴力玄學出奇跡??#$%^&*
其中F題用vector開多維數組的方法很實用,拿小本本記下來(doge)
代碼如下:
A題
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
typedef long long ll;
inline int read() {
int x=0;char c=getchar();
while (c<'0'||c>'9') c=getchar();
while (c>='0'&&c<='9') x=x*10+c-'0',c=getchar();
return x;
}
int c[6];
int main() {
for (int i=1;i<=5;++i) scanf("%d",&c[i]);
for (int i=1;i<=5;++i) {
if (!c[i]) {
printf("%d\n",i);
return 0;
}
}
return 0;
}
B題
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
typedef long long ll;
inline int read() {
int x=0;char c=getchar();
while (c<'0'||c>'9') c=getchar();
while (c>='0'&&c<='9') x=x*10+c-'0',c=getchar();
return x;
}
int x,y;
int main() {
scanf("%d%d",&x,&y);
bool ok=false;
if (4*x-y>=0&&(4*x-y)%2==0&&y-2*x>=0&&(y-2*x)%2==0)
ok=true;
puts(ok?"Yes":"No");
return 0;
}
C題
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
typedef long long ll;
const int N=104;
bool vis[N];
inline int read() {
int x=0;char c=getchar();
while (c<'0'||c>'9') c=getchar();
while (c>='0'&&c<='9') x=x*10+c-'0',c=getchar();
return x;
}
int x,n,t;
int main() {
scanf("%d%d",&x,&n);
for (int i=1;i<=n;++i) {
scanf("%d",&t);
vis[t]=true;
}
for (int d=0;;++d) {
int ans=-1;
if (!vis[x-d]) ans=x-d;
else if (!vis[x+d]) ans=x+d;
if (~ans) {
printf("%d\n",ans);
return 0;
}
}
}
D題
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
typedef long long ll;
const int N=2e5+4;
const int A=1e6+4;
int vis[A];
int n,a[N];
inline int read() {
int x=0;char c=getchar();
while (c<'0'||c>'9') c=getchar();
while (c>='0'&&c<='9') x=x*10+c-'0',c=getchar();
return x;
}
int main() {
// freopen("in3.txt","r",stdin);
n=read();
for (register int i=1;i<=n;++i) {
a[i]=read();
++vis[a[i]];
}
int cnt=0;
for (register int i=1;i<=n;++i) {
if (vis[1]) {
if (a[i]^1) continue;
else if (vis[1]>1) continue;
else {
++cnt;
continue;
}
}
if (vis[a[i]]>1) continue;
bool ok=true;
for (int x=2;x*x<=a[i];++x)
if (a[i]%x==0) {
int y=a[i]/x;
if (vis[x]||vis[y]) {
ok=false;
break;
}
}
cnt+=ok;
}
printf("%d\n",cnt);
return 0;
}
E題
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<set>
using namespace std;
typedef long long ll;
const int N=2e5+4;
const int INF=0x3f3f3f3f;
int m=2e5;
int n,q,a[N];
multiset<int> s[N],ans;
int bel[N],mx[N];
inline int read() {
int x=0;char c=getchar();
while (c<'0'||c>'9') c=getchar();
while (c>='0'&&c<='9') x=x*10+c-'0',c=getchar();
return x;
}
int main() {
// freopen("in1.txt","r",stdin);
n=read(),q=read();
for (register int i=1;i<=n;++i) {
a[i]=read(),bel[i]=read();
s[bel[i]].insert(a[i]);
}
multiset<int>::iterator it;
for (register int i=1;i<=m;++i) {
if (!s[i].size()) continue;
it=s[i].end();
--it;
ans.insert(*it);
mx[i]=*it;
}
while (q--) {
int i=read(),ori=bel[i],tar=read();
bel[i]=tar;
it=ans.lower_bound(mx[ori]);
ans.erase(it);
if (mx[tar]) {
it=ans.lower_bound(mx[tar]);
ans.erase(it);
}
it=s[ori].lower_bound(a[i]);
s[ori].erase(it);
if (s[ori].size()) {
it=s[ori].end();
--it;
mx[ori]=*it;
} else {
mx[ori]=0;
}
s[tar].insert(a[i]);
it=s[tar].end();
--it;
mx[tar]=*it;
if (mx[ori]) ans.insert(mx[ori]);
ans.insert(mx[tar]);
it=ans.begin();
printf("%d\n",*it);
}
return 0;
}
F題
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<utility>
#include<cmath>
#include<vector>
#include<queue>
using namespace std;
typedef long long ll;
const ll INF=1e13;
const int N=1e6+4;
const int dx[4]={0,-1,0,1};
const int dy[4]={-1,0,1,0};
int n,m,K;
int sx,sy,tx,ty;
char s[N];
struct Node {
int dir,x,y;
};
inline int read() {
int x=0;char c=getchar();
while (c<'0'||c>'9') c=getchar();
while (c>='0'&&c<='9') x=x*10+c-'0',c=getchar();
return x;
}
inline void smin(ll &x,ll y) {
x=x>y?y:x;
}
inline ll f(ll x) {
ll res=x%K;
return res?x+K-res:x;
}
int main() {
// freopen("in.txt","r",stdin);
n=read(),m=read(),K=read();
sx=read(),sy=read(),tx=read(),ty=read();
vector<vector<vector<ll> > > dis(4,vector<vector<ll> >(n+1,vector<ll>(m+1,INF)));
vector<vector<vector<bool> > > vis(4,vector<vector<bool> >(n+1,vector<bool>(m+1,false)));
vector<vector<char> > mp(n+1,vector<char>(m+1,'\0'));
for (int i=1;i<=n;++i) {
scanf("%s",s+1);
for (int j=1;j<=m;++j) mp[i][j]=s[j];
}
//SPFA
queue<Node> q;
for (int dir=0;dir<4;++dir) {
dis[dir][sx][sy]=0;
vis[dir][sx][sy]=true;
q.push((Node){dir,sx,sy});
}
while (!q.empty()) {
Node cur=q.front();
q.pop();
int cdir=cur.dir,cx=cur.x,cy=cur.y;
vis[cdir][cx][cy]=false;
int nx=cx+dx[cdir],ny=cy+dy[cdir];
if (nx&&nx<=n&&ny&&ny<=m&&mp[nx][ny]=='.') {
//when this is false, mp[][] might explode if nx==n+1 or ny==m+1
if (dis[cdir][nx][ny]>dis[cdir][cx][cy]+1) {
dis[cdir][nx][ny]=dis[cdir][cx][cy]+1;
if (!vis[cdir][nx][ny]) {
vis[cdir][nx][ny]=true;
q.push((Node){cdir,nx,ny});
}
}
}
for (int dir=0;dir<4;++dir) {
if (dis[dir][cx][cy]>f(dis[cdir][cx][cy])) {
dis[dir][cx][cy]=f(dis[cdir][cx][cy]);
if (!vis[dir][cx][cy]) {
vis[dir][cx][cy]=true;
q.push((Node){dir,cx,cy});
}
}
}
}/*
for (int dir=0;dir<4;++dir) {
for (int i=1;i<=n;++i) {
for (int j=1;j<=m;++j)
printf("%lld ",dis[dir][i][j]);
puts("");
}
puts("");
}*/
ll ans=INF;
for (int dir=0;dir<4;++dir) {
dis[dir][tx][ty]=f(dis[dir][tx][ty]);
smin(ans,dis[dir][tx][ty]);
}
printf("%d\n",ans<INF?ans/K:-1);
return 0;
}