codeforce(286)div2

  昨天的DIV2挂零了·····这是个悲伤的故事····

 第一题,你加一个字符是否形成回文,正解是枚举字母的位置,最开始想到了,觉得麻烦····就没有写,之后就挂了····

#include
#include
#include
#include
#include
#include
#include
#include

#define ll __int64
#define MAX 1000009
using namespace std;

int pp(string a)
{
    int len = a.size();
    int flag = 0;
    for(int i = 0; i<len/2; i++)
    {
        if(a[i]!=a[len-i-1])
        {
            flag = 1;
            break;
        }
    }
    if(flag)
        return 0;
    else
        return 1;
}
int main()
{
    string str;
    string sq,sw,ps,sp;
    map<char,int>dp;
    cin>>str;
    int len1 = str.size();
    if(pp(str))
    {
        for(int i = 0; i<len1/2; i++)
        {
            sw+=str[i];
        }
        sw+=str[len1/2];
        for(int j = len1/2; j<len1; j++)
        {
            sw+=str[j];
        }
        cout<<sw<<endl;
    }
    else
    {
        for(int i = 0; i<len1; i++)
        {
            dp[str[i]]++;
        }
        for(int i = 0; i<len1; i++)
        {
            if(dp[str[i]]>2)
            {
                sq+=str[i];
            }
            if(dp[str[i]]<2)
            {
                sq+=str[i];
            }
        }
       // cout<
        int flag = 0;
        for(int j = 0; j<sq.size(); j++)
        {
            sp = str;
            for(int i = 0; i<str.size(); i++)
            {
                string sx;
                for(int l = 0; l<str.size(); l++)
                {
                    if(i == l)
                    {
                        sx+=sq[j];
                    }
                    sx+=str[l];
                }
                //cout<
                if(pp(sx))
                {
                    ps = sx;
                    flag = 1;
                    break;
                }
            }
            if(flag==0)
            {
                sp+=sq[j];
                if(pp(sp))
                {
                    ps = sp;
                    flag = 1;
                    break;
                }
            }
        }
        if(flag)
        {
            cout<<ps<<endl;
        }
        else
            cout<<"NA"<<endl;

    }
    return 0;
}
额,我先判断本身是不是回文,如果是中间加一个····注意 AAA 和AAAA,还有ever这样的样例,就能过了,我就是卡在ever上了···

第二题,问你联通的路径上有几种颜色,目前我知道两个方法,并查集和floyd。

最开始是想用floyd的,当时脑袋太死,只想到二维,其实这道题,是三维的,最后一维是颜色;

也就是dp[i][j][k]。

#include
#include
#include
#include
#include
#include
#include


#define ll __int64
#define MAX 1000009
#define MAXN 5555


using namespace std;
int dp[105][105][105];


int main()
{
    int n,m;
    int a,b,c;
    cin>>n>>m;
    while(m--)
    {
        cin>>a>>b>>c;
        dp[a][b][c] = dp[b][a][c] = 1;
    }
    for(int k = 1;k<=n;k++)
    {
        for(int i = 1;i<=n;i++)
        for(int j = 1;j<=n;j++)
        {
            for(int c = 1;c<=100;c++)
            {
                if(dp[i][k][c]&&dp[k][j][c])
                {
                    dp[i][j][c] = 1;
                }
            }
        }
    }
    int t;
    int x,y;
    int sum;
    cin>>t;
    while(t--)
    {
        cin>>x>>y;
        sum = 0;
        for(int c = 1;c<=100;c++)
        {
            if(dp[x][y][c]==1)
            {
                sum++;
            }
        }
        cout<     }
    return 0;
}

这样最后直接判断x,y下有多少种颜色就可以了。

第二种方法并查集,这里的并查集要开二维,第一维代表颜色,第二维,代表路径

也就是p[c][x];

#include
using namespace std;
int p[110][110];
int find(int x,int c)
{
return p[c][x]==x?x:p[c][x]=find(p[c][x],c);
}
void U(int a,int b,int c)
{
p[c][find(b,c)]=find(a,c);
}
int main()
{
for(int i=0;i<110;i++)
for(int j=0;j<110;j++)
p[i][j]=j;
int N,M;
scanf("%d %d",&N,&M);
for(int i=0;i{
int a,b,c;
scanf("%d %d %d",&a,&b,&c);
U(a,b,c);
}
int Q;
scanf("%d",&Q);
while(Q--)
{
int a,b;
scanf("%d %d",&a,&b);
int ans=0;
for(int i=1;i<=M;i++)
if(find(a,i)==find(b,i))
ans++;
printf("%d\n",ans);
}
}

这个两个都是CF上的代码····偷学的,觉的思想好好····学习算法就应该活

你可能感兴趣的:(ACM-ICPC)