调表。
手表可以加上1或者加上k,如果超过了n,就会自动减去n。问所有点到所有点在最优解的情况下,最大需要的调整次数。
n,k<1e6
妈的,就是一个zz dp,我居然去用bfs做了。好气!
#include<iostream>
#include<cstring>
using namespace std;
const int maxn = 1e6 + 5;
const int INF = 0x3f3f3f3f;
int n,k;
int dp[maxn];
inline int mmin(int a, int b){
return a<b?a:b;
}
bool flag = 0;
int main()
{
std::ios::sync_with_stdio(false);
cin>>n>>k;
bool flag = 0;
int ans = -1;
memset(dp,INF,sizeof(dp));
dp[0] = 0;
do{
int i;
flag = 0;
for(i=0;i<n;i++){
int temp = dp[i];
dp[i] = mmin(dp[i],mmin(dp[(i-1+n) % n] + 1,dp[(i-k+n) % n] + 1));
if(dp[i] != temp)
flag = 1;
}
}while(flag);
for(int i=0;i<n;i++){
if(dp[i] > ans)
ans = dp[i];
}
cout<<ans<<endl;
return 0;
}
---------------------------------------------------更新分割线--------------------------------------------------------------------
#include<bits/stdc++.h>
using namespace std;
const int maxn = 1e6 + 6;
int n,k;
int ans = -1;
inline int mmax(int a,int b){
return a>b?a:b;
}
struct node{
int idx,step;
node(){}
node(int idx,int step):idx(idx),step(step){}
};
int vis[maxn];
int bfs(){
queue<node> q;
q.push(node(0,0));
vis[0] = 1;
node u;
while(!q.empty()){
u = q.front();
q.pop();
int idx = u.idx;
int step = u.step;
if(vis[(idx + 1) % n] == 0){
vis[(idx + 1) % n] = 1;
q.push(node((idx + 1) % n,step+1));
ans = mmax(ans,step+1);
}
if(vis[(idx + k) % n] == 0){
vis[(idx + k) % n] = 1;
q.push(node((idx + k) % n,step+1));
ans = mmax(ans,step+1);
}
}
return ans;
}
int main()
{
cin>>n>>k;
cout<<bfs()<<endl;
return 0;
}