暴力??

需要注意的 专栏收录该内容
15 篇文章 0 订阅

又是苹果

Time Limit : 2000/1000ms (Java/Other)   Memory Limit : 65535/32768K (Java/Other)
Total Submission(s) : 54   Accepted Submission(s) : 12

Font: Times New Roman | Verdana | Georgia

Font Size:  

Problem Description

最近,亮亮和小W都对苹果很感兴趣!在研究了“最大苹果矩阵”和“给苹果树施肥”的问题后,他们又遇到了一个新的问题:

有一块长n米、宽m米的地,现在小W把地划分成边长1米的小正方形块,共n*m个块。每个块中可能种有一棵苹果树,或放有一个iPhone,也可以什么也没有。然而,亮亮拥有一种超能力,可以将2个宽1米、长度相同的矩形块在空间中直接交换。

亮亮经常对着农场施展超能力,为了不把自己搞晕,他每次总是选择两整行(长度均为m米)或两整列(长度均为n米)进行交换。小W对此十分恼火————当他想拿iPhone打游戏时,却莫名其妙地撞在了苹果树上。小W要求你写一个程序,帮助他确定某一正方形块中放了什么东西。

Input

输入包含多组数据,请处理到文件结束。
每组数据,第一行2个整数n、m,表示地的尺寸。
之后n行,每行m个英文字母,大写的T表示这里种有苹果树,小写的i表示这里放有iPhone,其他字符表示这里什么也没有。
之后1行,一个整数Q,表示小W询问的次数。
之后Q行,包含3个整数,可能有以下情况:
1 i1 j1 表示小W想知道第i1行第j1列的方块中有什么东西。
2 i1 i2 表示亮亮交换了第i1行与第i2行。
3 j1 j2 表示亮亮交换了第j1列与第j2列。
对于100%的数据,有1<=n*m<=10^6,1<=Q<=10^5,1<=i1,i2<=n,1<=j1,j2<=m。

Output

对于每组数据,输出以一行“Case #x:”开头,x表示数据的编号,从1开始。
对于小W的每次格式为“1 i j”的询问,输出一行。若方块中是苹果树,输出"Tree"。若方块中是iPhone,输出“Phone”。若方块中什么也没有,输出“Empty”。

Sample Input

2 2
Ti
Ti
2
1 1 1
1 2 2
3 3
Tct
Iai
qqT
3
1 1 3
2 1 2
1 1 3

Sample Output

Case #1:
Tree
Phone
Case #2:
Empty
Phone

Hint

输入数据只保证n*m在10^6以内,也就是说n和m都可能高达10^6。直接开10^6*10^6的数组肯定会MLE,请使用malloc或vector按需分配内存。

Author

xry111

直接模拟,两种交换操作的时间复杂度分别是O(n)、O(m),最坏情况下总时间复杂度为O(Q × max(n, m) + nm)显然会超时。注意到,如果连续进行一次行交换操作和一次列交换操作,无论这两次操作顺序如何,结果都不受影响。因此,对于行和列的交换操作,可分别定义表line和row,表示当前的第i行是原来的第line[i]行,第j列是原来的第row[j]列。这样,对于每次交换操作,只要交换两个数就行了,时间复杂度是O(1)。对于查询第i行j列的操作,直接返回原矩阵第line[i]行,row[j]列的元素就行了,时间复杂度O(1)。总的时间复杂度O(Q + nm)。

#include<cstring>
#include<cstdio>
#include<iostream>
#include<cmath>
#include<algorithm>
using namespace std;
typedef long long LL;
int A[1000005];
char s[1000005];
int r[1000005],c[1000005];
char ans[3][20]={"Phone","Empty","Tree"};
int main()
{
    int n,m;
    int cas=1;
    while(~scanf("%d%d",&n,&m))
    {
       //memset(A,0,n*m*sizeof(int));
       int cnt=0;
       for(int i=1;i<=n;i++)r[i]=i;
       for(int j=1;j<=m;j++)c[j]=j;
       for(int i=1;i<=n;i++)
       {
           r[i]=i;
           scanf("%s",s);
           int len=strlen(s);
           for(int j=0;j<len;j++)
           {
               if(s[j]=='T')A[++cnt]=1;
               else if(s[j]=='i')A[++cnt]=-1;
               else A[++cnt]=0;
           }
       }
       int Q,a,b,op;
       cin>>Q;
       printf("Case #%d:\n",cas++);
       while(Q--)
       {
           scanf("%d%d%d",&op,&a,&b);
           if(op==1)
           {
               int x=A[(r[a]-1)*m+c[b]];
               puts(ans[x+1]);
           }
           else if(op==2)
           {
               int t=r[a];
               r[a]=r[b];
               r[b]=t;
           }
           else
           {
               int t=c[a];
               c[a]=c[b];
               c[b]=t;
           }
       }
    }
    return 0;
}



  • 1
    点赞
  • 0
    评论
  • 0
    收藏
  • 一键三连
    一键三连
  • 扫一扫,分享海报

相关推荐
©️2020 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值