bestcoder round 81 div 1

Matrix

 
 Accepts: 171
 
 Submissions: 350
 Time Limit: 3000/1500 MS (Java/Others)
 
 Memory Limit: 131072/131072 K (Java/Others)
问题描述
有一个nnmm列的矩阵(1 \leq n \leq 1000 ,1 \leq m \leq 1000 )(1n1000,1m1000),在这个矩阵上进行qq  (1 \leq q \leq 100,000)(1q100,000) 个操作:

1 x y: 交换矩阵MM的第xx行和第yy(1 \leq x,y \leq n)(1x,yn);
2 x y: 交换矩阵MM的第xx列和第yy(1 \leq x,y \leq m)(1x,ym);
3 x y: 对矩阵MM的第xx行的每一个数加上y(1 \leq x \leq n,1 \leq y \leq 10,000)y(1xn,1y10,000);
4 x y: 对矩阵MM的第xx列的每一个数加上y(1 \leq x \leq m,1 \leq y \leq 10,000)y(1xm,1y10,000);
输入描述
输入包含多组数据. 第一行有一个整数T (1\leq T\leq 15)T(1T15), 表示测试数据的组数. 对于每组数据:
第一行输入3个整数nn, mm, qq.
接下来的nn行,每行包括mm个整数,表示矩阵MM(1 \leq M_{i,j} \leq 10,000),(1 \leq i \leq n,1 \leq j \leq m)(1Mi,j10,000),(1in,1jm).
最后qq行,每行输入三个整数a(1 \leq a \leq 4)a(1a4), xx, yy
输出描述
对于每组数据,输出经过所有qq个操作以后的矩阵MM
输入样例
2
3 4 2
1 2 3 4
2 3 4 5
3 4 5 6
1 1 2
3 1 10
2 2 2
1 10
10 1
1 1 2
2 1 2
输出样例
12 13 14 15
1 2 3 4
3 4 5 6
1 10
10 1
Hint
建议使用scanf / printf 代替 cin / cout
用数组来表示某行实际是第几行,某列实际是第几列
#include<cstdio>
#include<iostream>
#include<cstring>
using namespace std;
int t,n,m,q,x,y,z;
int tree[1005][1005];
int a[1005],b[1005];
int adx[1005],ady[1005];
int main()
{
    cin>>t;
    while(t--) 
    {
        scanf("%d%d%d",&n,&m,&q);
        for(int i=1;i<=n;i++) a[i]=i;
        for(int i=1;i<=m;i++) b[i]=i;
        for(int i=1;i<=n;i++) 
        for(int j=1;j<=m;j++) scanf("%d",&tree[i][j]);
        memset(adx,0,sizeof(adx));
        memset(ady,0,sizeof(ady));
        for(int i=1;i<=q;i++) 
        {
            scanf("%d%d%d",&x,&y,&z);
            if(x==1) swap(a[y],a[z]);
            if(x==2) swap(b[y],b[z]);
            if(x==3) adx[a[y]]+=z;
            if(x==4) ady[b[y]]+=z;
        }
        for(int i=1;i<=n;i++) 
        {
            for(int j=1;j<m;j++) 
            printf("%d ",tree[a[i]][b[j]]+adx[a[i]]+ady[b[j]]);
            printf("%d\n",tree[a[i]][b[m]]+adx[a[i]]+ady[b[m]]);
        }
    }
    return 0;
}

String

 
 Accepts: 115
 
 Submissions: 264
 Time Limit: 2000/1000 MS (Java/Others)
 
 Memory Limit: 65536/65536 K (Java/Others)
问题描述
有一个 10\leq10长度\leq 1,000,0001,000,000 的字符串,仅由小写字母构成。求有多少个子串,包含有至少k(1 \leq k \leq 26)k(1k26)个不同的字母?
输入描述
输入包含多组数据. 第一行有一个整数T (1\leq T\leq 10)T(1T10), 表示测试数据的组数. 对于每组数据:
第一行输入字符串SS。
第二行输入一个整数kk
输出描述
对于每组数据,输出符合要求的子串的个数。
输入样例
2
abcabcabca
4
abcabcabcabc
3
输出样例
0
55
这种头尾指针枚举,比赛的时候居然打错了。。。。。。
错误的代码(少了最后的一次头指针增加)
#include<cstdio>
#include<iostream>
#include<cstring>
int t,w,n,m,now,cas;
char a[1000005];
int have[200],le[200];
long long ans;
using namespace std;
int main()
{
    cin>>cas;
    while(cas--) 
    {
        scanf("%s",a+1);
        scanf("%d",&m);
        n=strlen(a+1);
        now=0;ans=0;
        memset(have,0,sizeof(have));
        memset(le,0,sizeof(le));
        t=1;w=10000000;
        for(int i=1;i<=n;i++) 
        {
            have[a[i]]++;
            if(le[a[i]]==0) 
            {
                le[a[i]]=1;
                now++;
            }
            if(now>=m) 
            {
                w=i;
                ans=ans+n-w+1;
                break;
            }
        }
        for(int i=w+1;i<=n;i++) 
        {
            while(now>=m) 
            {
                have[a[t]]--;
                if(have[a[t]]==0) 
                {
                    le[a[t]]=0;
                    now--;
                }
                if(now>=m) ans=ans+n-w+1;
                t++;
            }
            have[a[i]]++;
            if(le[a[i]]==0) 
            {
                le[a[i]]=1;
                now++;
            }
            if(now>=m) 
            {
                w=i;
                ans=ans+n-w+1;
            }
        }
        cout<<ans<<endl;
    }
    return 0;
}

AC的代码
#include<cstdio>
#include<iostream>
#include<cstring>
int t,w,n,m,now,cas;
char a[1000005];
int have[200],le[200];
long long ans;
using namespace std;
int main()
{
    cin>>cas;
    while(cas--) 
    {
        scanf("%s",a+1);
        scanf("%d",&m);
        n=strlen(a+1);
        now=0;ans=0;
        memset(have,0,sizeof(have));
        memset(le,0,sizeof(le));
        t=1;w=0;
        for(int i=1;i<=n;i++) 
        {
            if(le[a[i]]==0) 
            {
                le[a[i]]=1;
                now++;    
            }
            have[a[i]]++;
            if(now==m) w=i;
            while(now==m) 
            {
                ans=ans+n-w+1;
                have[a[t]]--;
                if(have[a[t]]==0) 
                {
                    le[a[t]]=0;
                    now--;
                }
                t++;
            }
        }
        cout<<ans<<endl;
    }
    return 0;
}









你可能感兴趣的:(bestcoder round 81 div 1)