test 2017 9.18

排列

题目描述
给定一个n*n的矩阵f,你需要求出有多少个1~n的排列x满足对于1<=i≠j<=n,均有f[i,j]=min(x[i],x[j]),并输出字典序最小的一个。

有多组数据。

输入
第一行一个整数t表示数据组数。
每组数据第一行一个正整数n。接下来n行每行n个整数,第i行第j列的整数表示f[i,j]。

输出
对于每组数据,如果不存在这样的排列,输出一行一个整数-1。否则输出两行,第一行一个整数表示排列个数对998244353取模的结果,第二行n个整数表示字典序最小的排列。

样例输入
1
2
0 1
1 0
样例输出
2
1 2
提示
对于20%的数据,n<=8。
对于60%的数据,n<=40。
对于100%的数据,t<=10,∑n<=2000,f[i,i]=0,1<=fi,j<=n。
各档数据中均有一半保证全部有解。

Solution

可得答案只有-1或2,简单判断不合法情况。

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
#define ll long long
using namespace std;
const int mod=998244353;
int cas,n,x;
ll ans;
int a[2005][2005];
int b[2005][2],c[2005],p[2005];
void prepare()
{
    cin>>n;
    for(int i=1;i<=n;i++)
    for(int j=1;j<=n;j++) scanf("%d",&a[i][j]);
    ans=1;
    for(int i=1;i<=n;i++) c[i]=b[i][0]=b[i][1]=p[i]=0;
}
void first()
{
    for(int i=1;i<=n;i++)
    for(int j=i+1;j<=n;j++)
    {
        if(a[i][j]!=a[j][i]) ans=-1;
        if(a[i][j]==n) ans=-1;
        x=a[i][j];
        if(c[x]==0) //此值还没出现过
        {
            b[x][0]=i;b[x][1]=j;c[x]=2;
        }
        else
        {
            if(c[x]==2) //第一次,要找公共部分
            {
                if(b[x][0]==i||b[x][1]==i)
                {
                    c[x]=1;b[x][0]=i;
                }
                else
                if(b[x][0]==j||b[x][1]==j)
                {
                    c[x]=1;b[x][0]=j;
                }
                else ans=-1;
            }
            else
            if(c[x]==1)
            {
                if(b[x][0]!=i&&b[x][0]!=j) ans=-1;
            }
        }
    }
}
void second()
{
    for(int i=1;i<n;i++)
    if(c[i]==1) //i值只对应一个下标
    {
        if(p[b[i][0]]==0) p[b[i][0]]=i; else ans=-1; //不合法
    }
    for(int i=1;i<n;i++)
    if(c[i]==2)
    {
        if(p[b[i][0]]==0&&p[b[i][1]]==0)
        {
            ans=ans*2;
            p[b[i][0]]=i;p[b[i][1]]=n;
        }
        else
        if(p[b[i][0]]>0&&p[b[i][1]]>0) ans=-1;
        else
        if(p[b[i][0]]==0) p[b[i][0]]=n;
        else
        if(p[b[i][1]]==0) p[b[i][1]]=n;
    }
}
int main()
{
    cin>>cas;
    while(cas--)
    {
        prepare();
        first();
        second();
        if(n==1)
        {
            if(a[1][1]==0)
            {
                cout<<"1"<<endl;
                cout<<"1 "<<endl;
            }
            else cout<<"-1"<<endl;
            continue;
        }
        if(ans<0) ans=-1;
        printf("%d\n",ans);
        if(ans>0)
        {
            for(int i=1;i<n;i++) printf("%d ",p[i]);
            printf("%d \n",p[n]);
        }
    }
    return 0;
}

字符串

题目描述
定义两个字符串A,B相似当且仅当满足以下两个条件中的至少一个:
(1)A和B相同;
(2)将A分为长度相同的两个子串A0,A1,将B分为长度相同的两个子串B0,B1,满足A0相似于B0,A1相似于B1或A0相似于B1,A1相似于B0。
给定两个字符串S,T,问它们是否相似。
有多组数据。

输入
第一行一个整数t表示数据组数。
每组数据第一行一个字符串S,第二行一个字符串T,保证它们长度相同。

输出
每组数据一行,若相似输出YES,不相似输出NO。

样例输入
2
abab
baab
aabb
abab
样例输出
YES
NO
提示
对于30%的数据,|S|<=30。
对于60%的数据,|S|<=100。
对于100%的数据,t<=30,∑|S|<=500000。

Solution

直接暴力递归

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;
char a[500005],b[500005];
int n,cas;
int ty(int x1,int y1,int x2,int y2)
{
    int l=y1-x1+1,x=x1,y=x2,s=0;
    while(l--) 
    {
        if(a[x]==b[y]) s++;
        x++;
        y++;
    }
    if(s==y1-x1+1) return 1; //ПаµИ
    if((y1-x1+1)%2==1) return 0;
    int mid1=(x1+y1)/2,mid2=(x2+y2)/2;
    if(ty(x1,mid1,x2,mid2)==1&&ty(mid1+1,y1,mid2+1,y2)==1) return 1;
    if(ty(x1,mid1,mid2+1,y2)==1&&ty(mid1+1,y1,x2,mid2)==1) return 1;
    return 0;
}   
int main()
{
    cin>>cas;
    while(cas--) 
    {
        scanf("%s",a+1);
        scanf("%s",b+1);
        n=strlen(a+1);
        if(ty(1,n,1,n)==1) printf("YES\n"); else printf("NO\n");
    }
    return 0;
}
zjh@ubuntu:~/samba/wificall_655/vine5_orig/PLATFORM/test$ sudo apt-get install libncurses5 [sudo] password for zjh: Reading package lists... Done Building dependency tree Reading state information... Done The following additional packages will be installed: libtinfo5 The following NEW packages will be installed: libncurses5 libtinfo5 0 upgraded, 2 newly installed, 0 to remove and 259 not upgraded. Need to get 180 kB of archives. After this operation, 864 kB of additional disk space will be used. Do you want to continue? [Y/n] Y Get:1 http://rdsource.tp-link.com/ubuntu focal-updates/universe amd64 libtinfo5 amd64 6.2-0ubuntu2.1 [83.4 kB] Get:2 http://rdsource.tp-link.com/ubuntu focal-updates/universe amd64 libncurses5 amd64 6.2-0ubuntu2.1 [96.9 kB] Fetched 180 kB in 1s (168 kB/s) Selecting previously unselected package libtinfo5:amd64. (Reading database ... 178282 files and directories currently installed.) Preparing to unpack .../libtinfo5_6.2-0ubuntu2.1_amd64.deb ... Unpacking libtinfo5:amd64 (6.2-0ubuntu2.1) ... Selecting previously unselected package libncurses5:amd64. Preparing to unpack .../libncurses5_6.2-0ubuntu2.1_amd64.deb ... Unpacking libncurses5:amd64 (6.2-0ubuntu2.1) ... Setting up libtinfo5:amd64 (6.2-0ubuntu2.1) ... Setting up libncurses5:amd64 (6.2-0ubuntu2.1) ... Processing triggers for libc-bin (2.31-0ubuntu9.18) ... zjh@ubuntu:~/samba/wificall_655/vine5_orig/PLATFORM/test$ zjh@ubuntu:~/samba/wificall_655/vine5_orig/PLATFORM/test$ zjh@ubuntu:~/samba/wificall_655/vine5_orig/PLATFORM/test$ ./aarch64-openwrt-linux-musl-gdb-stripped uclited core-uclited ./aarch64-openwrt-linux-musl-gdb-stripped: error while loading shared libraries: libncurses.so.5: cannot open shared object file: No such file or directory 安装了还是报这个错是为什么
最新发布
11-29
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值