CF1458C Latin Square
CF1458C Latin Square
題意:
T 組測試數據,每次給一個 n×nn\times nn×n 的矩陣,每行每列都是個 1→n1\to n1→n 的排列。有 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 n1≤i≤n有pqi=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。數據范圍:1≤T≤1000,1≤∑n≤1000,1≤∑m≤105,1≤ai,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的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Codeforces Round #73
- 下一篇: dsniff 和 Ettercap 和