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

歡迎訪問 生活随笔!

生活随笔

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

编程问答

CF1458C Latin Square

發布時間:2023/12/3 编程问答 31 豆豆
生活随笔 收集整理的這篇文章主要介紹了 CF1458C Latin Square 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

CF1458C Latin Square

題意:

T 組測試數據,每次給一個 n×nn\times nn×n 的矩陣,每行每列都是個 1→n1\to n1n 的排列。有 m 次操作,如果是 UDLR 就是要把整個矩陣每行/每列往一個方向循環移動一格。如果是 IC,就是把矩陣每行/每列變成原來的逆排列。求最后的矩陣。
逆排序定義:
一個序列p1,p2,....,pnp_{1},p_{2},....,p_{n}p1?,p2?,....,pn?的逆排序是q1,q2,...qnq_{1},q_{2},...q_{n}q1?,q2?,...qn?,對于所有1≤i≤n1\le i\le n1inpqi=ip_{q_{i}}=ipqi??=i

數據范圍:1≤T≤1000,1≤∑n≤1000,1≤∑m≤105,1≤ai,j≤n。數據范圍:1\le T\le 1000,1\le \sum n\le 1000,1\le \sum m\le 10^5 ,1\le a_{i,j}\le n。1T10001n10001m1051ai,j?n。

題解:

UDLR都好操作,我們只需要維護x和y分別移動了多少即可
但問題就是存在IC操作,就是這個逆排序如何理解?
對于排序p1,p2,....,pnp_{1},p_{2},....,p_{n}p1?,p2?,....,pn?,我們可以把每個元素看作是一個二維坐標(i,pi)(i,p_{i})(i,pi?),那么這個排序的逆元相當于(pi,i)(p_{i},i)(pi?,i),即交換兩維坐標
那么我們就可以把這個矩陣看作是三維空間里的點(x,y,ax,y)(x,y,a_{x,y})(x,y,ax,y?),III操作就是交換x和ax,ya_{x,y}ax,y?CCC操作就是交換了y和ax,ya_{x,y}ax,y?,LRUD就是正常的對x或y的修改
這樣,對于LRUD,記錄每一維的增量,對于IC,記錄當前每一維是原來的第幾維,這樣不就將所有操作O(1)解決了嗎
我們用數組p來記錄當前是第幾維,I,C操作就是交換數組p
秒啊~這個題
詳細看代碼

代碼:

#include <bits/stdc++.h> #include <unordered_map> #define debug(a, b) printf("%s = %d\n", a, b); using namespace std; typedef long long ll; typedef unsigned long long ull; typedef pair<int, int> PII; clock_t startTime, endTime; //Fe~Jozky const ll INF_ll= 1e18; const int INF_int= 0x3f3f3f3f; void read(){}; template <typename _Tp, typename... _Tps> void read(_Tp& x, _Tps&... Ar) {x= 0;char c= getchar();bool flag= 0;while (c < '0' || c > '9')flag|= (c == '-'), c= getchar();while (c >= '0' && c <= '9')x= (x << 3) + (x << 1) + (c ^ 48), c= getchar();if (flag)x= -x;read(Ar...); } template <typename T> inline void write(T x) {if (x < 0) {x= ~(x - 1);putchar('-');}if (x > 9)write(x / 10);putchar(x % 10 + '0'); } void rd_test() { #ifdef ONLINE_JUDGE #elsestartTime = clock ();freopen("data.in", "r", stdin); #endif } void Time_test() { #ifdef ONLINE_JUDGE #elseendTime= clock();printf("\nRun Time:%lfs\n", (double)(endTime - startTime) / CLOCKS_PER_SEC); #endif } const int maxn=2e3+9; int a[maxn*maxn][3]; int b[maxn][maxn]; int p[3]; int x[3]; int n,m; void add(int &x){//正向移動 x++;if(x>n)x-=n; } void del(int &x){//方向移動 x--;if(x<0)x+=n; } void solve(){read(n,m);for(int i=1;i<=n;i++){for(int j=1;j<=n;j++){int pos=(i-1)*n+j;int x;read(x);a[pos][0]=i;a[pos][1]=j;a[pos][2]=x;//存下三維信息 }}for(int i=0;i<3;i++){p[i]=i;x[i]=0; }string s;cin>>s;for(int i=0;i<m;i++){if(s[i]=='U')del(x[p[0]]);//行-- if(s[i]=='D')add(x[p[0]]);//行++if(s[i]=='L')del(x[p[1]]);//列-- if(s[i]=='R')add(x[p[1]]);//列++ if(s[i]=='I')swap(p[1],p[2]);//行逆排序,將列與值交換 if(s[i]=='C')swap(p[0],p[2]);//列逆排序 }for(int i=1;i<=n*n;i++){for(int j=0;j<3;j++)//執行對應操作 a[i][j]=(a[i][j]+x[j]-1)%n+1;b[a[i][p[0]]][a[i][p[1]]]=a[i][p[2]];//將變換后的值賦給b } for(int i=1;i<=n;i++){for(int j=1;j<=n;j++){printf("%d ",b[i][j]);}printf("\n"); } } int main() {rd_test();int t;read(t);while(t--){solve();}//Time_test(); }

總結

以上是生活随笔為你收集整理的CF1458C Latin Square的全部內容,希望文章能夠幫你解決所遇到的問題。

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