日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

JZOJ 4675. 【NOIP2016提高A组模拟7.21】Double-row

發布時間:2025/3/15 编程问答 17 豆豆
生活随笔 收集整理的這篇文章主要介紹了 JZOJ 4675. 【NOIP2016提高A组模拟7.21】Double-row 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

Description

科學家溫斯頓在一張超長的白紙上寫下了兩行數,每一行數有N個。
但他寫完后覺得看起來有點不和諧。他希望重新編排,使得每一行數中沒有相同的數。
他每次可以調換同一列的兩個數。
請幫他找到操作次數最少的方案。

Input

第一行一個正整數N,代表每一行數的個數。
第二第三行每行N個數,代表第一行與第二行的數值。

Output

第一行一個整數,表示最少的操作次數。數據保證合法的操作是存在的。

Sample Input

9
2 5 5 2 7 4 7 3 9
1 6 8 4 6 3 9 1 8

Sample Output

3

Hint

對于樣例數據,只需調換1,3,5列即可。

Data Constraint

設字符串的長度為N。
Subtask1[30pts]:N<=500
Subtask2[30pts]:N<=5000
Subtask3[40pts]:N<=50000
數值Xi滿足1<=X<=100000

Solution

  • 可以明顯得到同一個數不可能出現 3 次或以上,否則無解。

  • 如果同一個數出現在同一側(設其出現在 X 列和 Y 列),那么 X 列與 Y 列之中有且只有一列要調換;

  • 如果同一個數出現在不同一側(設其出現在 X 列和 Y 列),那么要么均不調換,要么均調換。

  • 我們把每一列看作一個點,這樣的關系用邊連起來,那么連通塊內相互影響,而連通塊之間
    是相互獨立的。

  • 所以分別處理每一個連通塊:隨機確定一列換不換,那么連通塊內其余的狀態都會被確定。

  • 我們只需選擇操作數少的即可。

Code

#include<cstdio> using namespace std; const int N=50001; int n,ans,sum,tot; int first[N],next[N<<1],en[N<<1],w[N<<1]; int a[N<<1],b[N<<1],f[N]; bool bz[N],bz1[N]; inline int read() {int X=0,w=1; char ch=0;while(ch<'0' || ch>'9') {if(ch=='-') w=-1;ch=getchar();}while(ch>='0' && ch<='9') X=(X<<3)+(X<<1)+ch-'0',ch=getchar();return X*w; } inline void insert(int x,int y,int z) {next[++tot]=first[x];first[x]=tot;en[tot]=y;w[tot]=z; } inline void dfs(int x) {sum+=f[x];bz[x]=true;for(int i=first[x];i;i=next[i])if(!bz[en[i]]){f[en[i]]=(f[x]+w[i])&1;dfs(en[i]);}f[x]=0; } inline void dfs1(int x) {sum+=f[x];bz1[x]=true;for(int i=first[x];i;i=next[i])if(!bz1[en[i]]){f[en[i]]=(f[x]+w[i])&1;dfs1(en[i]);} } int main() {n=read();for(int i=1;i<=n;i++){int x=read();if(!a[x]) a[x]=i; else{insert(i,a[x],1);insert(a[x],i,1);}}for(int i=1;i<=n;i++){int x=read();if(a[x]){insert(i,a[x],0);insert(a[x],i,0);}elseif(!b[x]) b[x]=i; else{insert(i,b[x],1);insert(b[x],i,1);}}for(int i=1;i<=n;i++)if(!bz[i]){sum=f[i]=0;dfs(i);int k=sum;sum=0,f[i]=1;dfs1(i);if(k<sum) sum=k;ans+=sum;}printf("%d",ans);return 0; } 與50位技術專家面對面20年技術見證,附贈技術全景圖

總結

以上是生活随笔為你收集整理的JZOJ 4675. 【NOIP2016提高A组模拟7.21】Double-row的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。