CodeForces - 765D Artsem and Saunders(数学化简+构造+思维)
生活随笔
收集整理的這篇文章主要介紹了
CodeForces - 765D Artsem and Saunders(数学化简+构造+思维)
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
題目鏈接:點擊查看
題目大意:給出一個序列f(x),要求我們構造出兩個序列g(x)和h(x),滿足:
到這里我們可以知道,因為g(x)和h(x)兩個函數的定義域一個是f(x)的定義域,一個是f(x)的值域,又因為f(x)的定義域一定是互不相同的n個數,而f(x)的值域沒說互不相同,所以最后g(x)一定是輸出n個數,而h(x)輸出的一定是f(x)值域中不相同的數的個數
換句話來說,g(x)和h(x)可以形成一個關于f(x)的雙映射,但因為g(x)是一對一,而h(x)是一對多,所以這個題目最后的答案不唯一
我們來稍微化簡一下吧:
我們現在假設任意兩個數t和A,使得g(t)=A,h(A)=t
因為g(h(x))=x和h(g(x))=f(x),所以t=h(A)=h(g(t))=f(t),這樣可以知道,當f(t)=t時,滿足g(t)=A,h(A)=t
這樣一來我們可以先將所有f(x)的值從1開始映射給h(x),期間將所有的g(x)按照規則賦值,因為h(x)的定義域一定是小于等于n的,所以處理完h(x)后,剩下的g(x)還沒有來得及賦值,初始值都為0,則我們可以再遍歷一遍f(x),此時給g(x)=0的重新賦值,給g(x)!=0的判斷一下是否合理即可
代碼:
#include<iostream> #include<cstdlib> #include<string> #include<cstring> #include<cstdio> #include<algorithm> #include<climits> #include<cmath> #include<cctype> #include<stack> #include<queue> #include<list> #include<vector> #include<set> #include<map> #include<sstream> using namespace std;typedef long long LL;const int inf=0x3f3f3f3f;const int N=1e6+100;int vis[N];int a[N];set<int>st;int cnt;int h[N],g[N];int main() { // freopen("input.txt","r",stdin); // ios::sync_with_stdio(false);int n; scanf("%d",&n);for(int i=1;i<=n;i++){scanf("%d",a+i);st.insert(a[i]);}for(auto it:st)//枚舉t {h[++cnt]=it;g[it]=vis[it]=cnt;}bool flag=false;for(int i=1;i<=n;i++){if(g[i]==0)//若g[i]==0,說明還沒有賦過值g[i]=vis[a[i]];else if(h[g[i]]!=a[i])//若g[i]!=0,判斷一下合理性{flag=true;break;}}if(flag)printf("-1");else{printf("%d\n",cnt);for(int i=1;i<=n;i++)printf("%d ",g[i]);printf("\n");for(int i=1;i<=cnt;i++)printf("%d ",h[i]);}return 0; }?
總結
以上是生活随笔為你收集整理的CodeForces - 765D Artsem and Saunders(数学化简+构造+思维)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: POJ - 2195 Going Hom
- 下一篇: CodeForces - 553C Lo