zoukankan      html  css  js  c++  java
  • poj3535 A+B (大数加法)

    A+B
    Time Limit: 2000MS   Memory Limit: 65536K
    Total Submissions: 811   Accepted: 371

    Description

    The Research Institute of Given Strings (RIGS) is a well-known place where people investigate anything about strings. Peter works in the department of string operations of RIGS. His department invents different ways to add, multiply, divide strings and even to take a logarithm of a string based on another one.

    Now Peter is involved in the new project concerning orthogonal strings. Peter proposed that two strings P = P1P2Pn and Q = Q1Q2Qn of equal length n are called orthogonal, if Pi ≠ Qi for each i in the range 1..n. String S of length n is called orthogonal to set of strings V = ‹V1V2, …, Vm› (each of length n too) if S is orthogonal to Vj for any j in range 1..m.

    Peter’s task is to invent the operation of orthogonal sum of two given strings. The current Peter’s proposal allows to add only strings on a basis of some set, if they are orthogonal to this set. To do this, Peter selects an arbitrary set of strings V such that all strings in V have the same length n. Then Peter takes all strings of length n orthogonal to V over a fixed alphabet and sorts them, thus obtaining a sorted sequence of strings T. Let’s denote the length of sequence T as M, and enumerate the elements of this sequence as T0T1, …, TM−1. Now Peter says that the orthogonal sum of two strings A = Ta and B = Tb is a string C = Tc where c = (a + b) modM.

    Your task is to find the orthogonal sum of two given strings A and B on the basis of a given set V over the alphabet of small English letters.

    Input

    The first line of the input file contains two integers: n — the length of each string (1 ≤ n ≤ 100 000) and k — the cardinality of V (1 ≤ n ⋅ k ≤ 100 000). The next k lines contains strings V1V2, …, Vk.

    The last two lines contain strings A and B of length n. All strings VjA and B consist of small letters of English alphabet. It is guaranteed that A and B are orthogonal to V.

    Output

    Output the orthogonal sum of strings A and B on the basis V.

    Sample Input

    #1 2 2
    ac
    ad
    bb
    bb
    #2 2 1
    yy
    zz
    zz

    Sample Output

    #1 be
    #2 zx

    题意:题意蛋疼。。 给出k个长度为n的字符串集合,再给出两个长度也是n的字符串AB。然后构建一个新的集合,要求集合里的每一个字符串都和原集合里每一个字符串正交,这里正交的意思是,对字符串P和Q的每一个位置有Pi 不等于 Qi 。新集合排序后,从0到M-1编号,然后就可以得到A、B在新集合的下标(数据保证A、B与原集合正交),把下标相加对M求余,得到新下标,此下标对应字符串为题目所求

    思路:把k条字符串每一个位置上出现过的字母记录下来,统计这个位置上还有多少个字母没出现过,那这个数字就是这个位置上的进制了,对A、B转换为进制数,然后就是进行一次大数加法了。例如题目给ac/ae,那数目分别为25/24,那么bb对应的数字就是01,bb+bb=01+01=02=be

    代码

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <cmath>
    #include <vector>
    #include <map>
    #include <utility>
    #include <queue>
    #include <stack>
    using namespace std;
    typedef pair<int,int> pii;
    const int INF=1<<30;
    const double eps=1e-6;
    const int N = 100010;
    char s[N],a[N],b[N],c[N];
    bool vis[N][30];
    int n,k,cnt[N];
    void rev(char *s)
    {
        int l=0,r=n-1;
        for(;l<r;l++,r--)
            swap(s[l],s[r]);
    }
    void read()
    {
        memset(vis,0,sizeof(vis));
        memset(cnt,0,sizeof(cnt));
        while(k--)
        {
            scanf("%s",s);
            rev(s);
            for(int i=0;i<n;++i)
                vis[i][s[i]-'a']=1;
        }
        for(int i=0;i<n;++i)
            for(int j=0;j<26;++j)
                if(!vis[i][j])
                    cnt[i]++;
    }
    int ctoint(int idx,char c)
    {
        c = c-'a';
        int res=0;
        for(int i=0;i<c;++i)
            if(!vis[idx][i])
                res++;
        return res;
    }
    char inttoc(int idx,int x)
    {
        int i;
        for(i=0;;i++)
            if(!vis[idx][i] && (x--)==0)
                break;
        return i+'a';
    }
    void run()
    {
        read();
        scanf("%s%s",a,b);
        rev(a);
        rev(b);
        int rem=0,tmp;
        for(int i=0;i<n;++i)
        {
            tmp = rem + ctoint(i,a[i]) + ctoint(i,b[i]);
            c[i] = tmp%cnt[i];
            rem = tmp/cnt[i];
        }
        for(int i=0;i<n;++i)
            c[i] = inttoc(i,c[i]);
        for(int i=n-1;i>=0;--i)
            putchar(c[i]);
        puts("");
    }
    
    int main()
    {
        freopen("case.txt","r",stdin);
        while(scanf("%d%d",&n,&k)!=EOF)
            run();
        return 0;
    }
  • 相关阅读:
    一种安全云存储方案设计(上)——基于二次加密的存储策略与加密图文混合检索
    lamda表达式导致运行时VerifyError
    编译原理:语法分析概述
    语音识别与 RNN-Transducer 概述
    通信原理基本概念
    追光捉影的自动机:2021 卓工实训小作文
    【实战】jsfinder+jsinfo-scan结合改造
    js基础记录
    qq、微信二次分享
    收藏链接
  • 原文地址:https://www.cnblogs.com/someblue/p/3932506.html
Copyright © 2011-2022 走看看