问题 I: Isomorphic Inversion

时间限制: 1 Sec 内存限制: 128 MB

提交 状态 题面

题目描述

Let s be a given string of up to 106 digits. Find the maximal k for which it is possible to partition s into k consecutive contiguous substrings, such that the k parts form a palindrome.

More precisely, we say that strings s0, s1, . . . , sk−1 form a palindrome if si = sk−1−i for all 0 ≤ i < k.

In the first sample case, we can split the string 652526 into 4 parts as 6|52|52|6, and these parts together form a palindrome. It turns out that it is impossible to split this input into more than 4 parts while still making sure the parts form a palindrome.

输入

A nonempty string of up to 106 digits.

输出

Print the maximal value of k on a single line.

样例输入

652526

样例输出

4

字符串哈希裸题,O(n)

#pragma GCC optimize(3,"Ofast","inline")
#include <stdio.h>
#include <iostream>
#include <algorithm>
#include <string.h>
#include <queue>
#include <vector>
#include <map>
#include <cmath>
#include <stack>
#include <set>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const int maxn = 1010;
const int MAXN = 1000010;
const int Hash = 13131;
const int mod =1e9+7;
ull base[MAXN],h[MAXN];
char str[MAXN];
void init(int n){
    base[0]=1;
    h[0]=Hash;
    for(int i=1;i<=n;i++){
        base[i]=base[i-1]*Hash;
        h[i]=h[i-1]*Hash+str[i];
    }
}
bool check(int l,int r,int len){
    //cout<<"checkl "<<l<<" "<<len<<" "<<h[l]-h[l-len]*base[len]<<endl;
    //cout<<"checkr "<<r<<" "<<len<<" "<<h[r+len-1]-h[r-1]*base[len]<<endl;
    return h[l]-h[l-len]*base[len]==h[r+len-1]-h[r-1]*base[len];
}
int main()
{
    scanf("%s",str+1);
    int len=strlen(str+1);
   // cout<<len<<endl;
    init(len);
    int ans=0;
    int anslen=0;
    for(int i=1,j=len;i<=(len>>1)&&j>=(len>>1);i++,j--){
        //cout<<i<<" "<<anslen<<endl;
        anslen++;
        if(check(i,j,anslen)){
            ans++;
            anslen=0;
        }
    }
    ans<<=1;
    //if(anslen==0)
    //
    //    ans+=len&1;
    if(len&1){
        ans++;
    }else{
        if(anslen!=0)
            ans++;
    }
    cout<<ans<<endl;
    return 0;
}

问题 H: H to O

时间限制: 1 Sec 内存限制: 128 MB

提交 状态 题面

题目描述

Professor Cesium has created a new process to transform some chemical product into another type of chemical with some residues. The process is simple: he just needs to input a given number of molecules of type A,enter the output type B he desires and start the machine. It will create as many molecules of type B as possible. Unfortunately, professor Cadmium was jealous of his work and tried to sabotage the machine by inverting wires on his machine. Professor Cesium, alerted by one of his assistants, was able to repair the mistake. To detect any problem in the future, he is asking you to create an automatic way to compute the number of molecules that the machine should output. With this algorithm, he will be able to detect whether his precious machine was tampered with.

Molecules are written as string composed of upper case letters and numbers. Upper case letters represent atoms. Note that Cesium only uses single letters of the alphabet as abbreviations for atoms, so H, C, A, X, Y, … can be used but He, Mg, … can not. If a letter is not followed by a number, it means there is only one atom of it. An atom followed by a number l (1 ≤ l < 103 ) represents l copies of that atom. Atoms can appear multiple times in a chemical product.

For example: H2OC100H means 2 atoms of H, then 1 of O, then 100 of C then 1 of H again.

输入

• The first line contains the input molecule, a string of length at most 2500, followed by an integer 1 ≤ k ≤ 103, denoting how many of these molecules professor Cesium has.

• The second line contains the desired output molecule, given as a string of length at most 2500.

输出

The output consists of a single line containing the maximum number n of output molecules we are able to construct using the input molecules.

样例输入

H 2

O

样例输出

0

#pragma GCC optimize(3,"Ofast","inline")
#include<bits/stdc++.h>
 
using namespace std;
typedef  long long ll;
const int N  = 1010;
typedef pair<int,int>P;
 
int vis[50],visg[50];
char s1[3000];
char s2[3000];
int main()
{
    int k;
    scanf("%s",s1);
    scanf("%d",&k);
    scanf("%s",s2);
    int ls=strlen(s1),lg=strlen(s2);
    for(int i=0;i<ls;i++)
    {
        if(isalpha(s1[i]))
        {
            int cnt=0;
            int t=i+1;
            while(isdigit(s1[t]))
            {
                cnt=cnt*10;
                cnt+=(s1[t]-'0');
                t++;
            }
           // cout<<cnt<<endl;
            if(cnt==0) vis[s1[i]-'A']++;
            else vis[s1[i]-'A']+=cnt;
            i=t-1;
        }
    }
    for(int i=0;i<=('Z'-'A');i++) vis[i]*=k;
    for(int i=0;i<lg;i++)
    {
        if(isalpha(s2[i]))
        {
            int cnt=0;
            int t=i+1;
            while(isdigit(s2[t]))
            {
                cnt=cnt*10;
                cnt+=(s2[t]-'0');
                t++;
            }
          //  cout<<cnt<<endl;
            if(cnt==0) visg[s2[i]-'A']++;
            else visg[s2[i]-'A']+=cnt;
            i=t-1;
        }
    }
   // cout<<1<<endl;
    int ans=0x3f3f3f3f;
   /* for(int i=0;i<=('Z'-'A');i++) cout<<vis[i]<<' '<<(char)('A'+i)<<endl;
    cout<<endl;
    for(int i=0;i<=('Z'-'A');i++) cout<<visg[i]<<' '<<(char)('A'+i)<<endl;*/
    for(int i=0;i<=('Z'-'A');i++)
    {
        if(visg[i])
        {
             //cout<<ans<<' '<<(char)('A'+i)<<endl;
            if(vis[i]) ans=min(ans,vis[i]/visg[i]);
            else
            {
                //cout<<1<<endl;
                ans=0;
                break;
            }
        }
    }
    printf("%d\n",ans);
    return 0;
}

问题 D: Daily Division

时间限制: 1 Sec 内存限制: 128 MB

提交 状态 题面

题目描述

Oostende Beach is a very long beach located in the north of Belgium. On this beach, there are n huts located along a straight line. People can rent a room in one of those huts to spend their beach vacations together with the other

tenants.

Every day at lunch time, a food truck rides by to serve fries to the guests. The truck will park in front of one of the huts and people will form two queues. The people staying in huts to the left of the food truck will queue on the left,and the people to the right of the food truck will queue together on the right. The people staying in the hut in front of the food truck will split their group in half, one half going to the left queue and the other half going to the right queue. If this is an odd number of people,the remaining person will go to the queue with fewer people, or choose one randomly if the queues have the same length. The food truck will always position itself so that the difference between the number of people in the left queue and the number of people in the right queue is as small as possible.

Each night the number of guests in exactly one of the huts changes. Can you help the food truck find the best position for each day?

输入

• The first line of the input consists of two integers 1 ≤ n ≤ 105, the number of huts, and 1 ≤ q ≤ 105, the number of days.

• The second line has n integers a0, . . . , an−1 satisfying 1 ≤ ai ≤ 106 for 0 ≤ i < n, where ai is the current number of people in hut i.

• Then follow q lines with two integers 0 ≤ i < n and 1 ≤ x ≤ 106. The jth of these lines indicates that at day j the number of people in hut i changes to x .

输出

Print q lines: the optimal position of the foodtruck after each of the q nights. If there are multiple optimal positions, print the smallest one.

样例输入

5 4

3 1 3 4 2

0 5

0 9

4 5

2 1

样例输出

2

1

2

1

线段树,区间查询的时候二分找中点,然后一定要注意,整体有单调性,但局部不一定有,二分找到后一定要看一下周围几个

学姐说可以直接找人数一般的那个房间,然后比较i、i+1、i-1哪个优用哪个就行

#pragma GCC optimize(3,"Ofast","inline")
#include<bits/stdc++.h>
 
using namespace std;
typedef  long long ll;
const int N  = 100010;
typedef pair<int,int>P;
 
ll ar[N];
int n,q;
ll nowp[N];
inline int lowbit(int x)
{
    return x&(-x);
}
 
inline void add(int i,ll v)
{
    for(;i<N;ar[i]+=v,i+=lowbit(i));
}
 
inline ll sum(int i)
{
    ll ans=0;
    for(;i>0;ans+=ar[i],i-=lowbit(i));
    return ans;
}
 
inline bool check(int x)
{
    ll suml=sum(x-1),sumr=sum(n)-suml-nowp[x];
    if(suml-sumr<0) return false;
    return true;
}
int searc()
{
    int l=1,r=n;
    while(r-l>1)
    {
        int mid=(l+r)>>1;
        if(check(mid)) r=mid;
        else l=mid;
    }
    //cout<<l<<' '<<r<<endl;
    ll suml1=sum(l-1),sumr1=sum(n)-suml1-nowp[l];
    ll suml2=sum(r-1),sumr2=sum(n)-suml2-nowp[r];
    if(nowp[l]&1)
    {
        if(suml1<sumr1) suml1++;
        else sumr1++;
    }
    if(nowp[r]&1)
    {
        if(suml2<sumr2) suml2++;
        else sumr2++;
    }
    if(abs(suml1-sumr1)<=abs(suml2-sumr2)) return l;
    return r;
}
int main()
{
    //freopen("a.txt","r",stdin);
    scanf("%d%d",&n,&q);
    for(int i=1;i<=n;i++)
    {
        scanf("%lld",&nowp[i]);
        add(i,nowp[i]);
    }
    while(q--)
    {
        int x;ll now;
        scanf("%d%lld",&x,&now);
        x++;
        add(x,now-nowp[x]);
        nowp[x]=now;
        int ans=searc();
        printf("%d\n",ans-1);
    }
    return 0;
}

问题 B: Bee Problem

时间限制: 1 Sec 内存限制: 128 MB

提交 状态 题面

题目描述

You are a busy little bee, and you have a problem. After collecting nectar all day long, you are returning to the beehive with a large supply of honey. You would really like to take a nap now, but sadly, you have to store all the honey in your beehive first. Opening up a cell in the hive to funnel honey into takes a lot of time, so you want to avoid doing this as much as possible.

Some of the cells in the beehive are already filled with old, hardened honey. The other cells are still empty. If you pour honey into an empty cell, it will automatically start flowing into adjacent empty cells. From these cells, the honey will again flow to other neighbouring empty cells. This saves you from having to funnel honey into them directly. You decide to use this to your advantage, by pouring into cells with lots of (indirect) adjacent open cells.

figure 1: The beehives from the first two samples. The black hexagons already contain hardened honey. The white cells are still empty.

You have some units of honey, and know the layout of your beehive. By cleverly choosing which cells to funnel honey into, what is the minimal amount of work you have to do?

输入

• The input starts with three integers, 0 ≤ h ≤ 106, the amount of honey you have, and 1 ≤ n, m ≤ 103, the dimensions of the grid.

• Then follow n lines, one for each row of the grid. Each row has m symbols, either .,representing an empty cell, or #, representing a filled cell. These symbols are separated by spaces. Furthermore, every second row starts with a space, as these are slightly offset to the right.

The grid always has enough open cells to store all your honey.

输出

Output a single integer, the number of cells you have to funnel honey into directly to store all your honey in the hive.

样例输入

8 4 4

. # # .

# . # .

# # # .

# . . .

样例输出

3

#pragma GCC optimize(3,"Ofast","inline")
#include<bits/stdc++.h>
 
using namespace std;
typedef  long long ll;
const int N  = 2010;
typedef pair<int,int>P;
 
int h,n,m,cnt;
 
char mp[N][N];
bool vis[N][N];
priority_queue<int>q;
int ar[6][2]={{1,1},{-1,1},{1,-1},{-1,-1},{0,2},{0,-2}};
 
void dfs(int x,int y)
{
    if(vis[x][y]) return ;
    vis[x][y]=true;
    cnt++;
    //cout<<x<<' '<<y<<endl;
    for(int i=0;i<6;i++)
    {
        int ax=x+ar[i][0],ay=y+ar[i][1];
        if(ax>0 && ay>0 && ax<=n && ay<=2*m && mp[ax][ay]=='.' && !vis[ax][ay]) dfs(ax,ay);
    }
}
int main()
{
    //freopen("a.txt","r",stdin);
    scanf("%d %d %d",&h,&n,&m);
    getchar();
    for(int i=1;i<=n;i++) gets(mp[i]+1);
    //for(int i=1;i<=n;i++) puts(mp[i]+1);
    for(int i=1;i<=n;i++)
    {
        int j;
        if(i&1) j=1;
        else j=2;
        for(;j<=2*m;j+=2)
        {
            cnt=0;
            if(!vis[i][j] && mp[i][j]=='.')
            {
                //cout<<endl;
                dfs(i,j);
                q.push(cnt);
            }
        }
    }
    int ans=0;
    while(h>0 && q.size())
    {
        h-=q.top();
        //cout<<h<<' '<<q.top()<<endl;
        q.pop();
        ans++;
    }
    printf("%d\n",ans);
    return 0;
}

问题 A: Appalling Architecture

时间限制: 1 Sec 内存限制: 128 MB

提交 状态 题面

题目描述

You have recently been hired as an architect for the BAPC (Bureau of Architecture and Promising Constructions), responsible for top-quality buildings such as the Tower of Pisa. However, in the past couple of weeks, some of the constructions that the BAPC has made have collapsed! It is up to you to figure out whether any other constructions are in danger.

After some research it seems like the x-coordinate of the center of gravity of some of the constructions is off: if this is too much to the left or to the right, the construction will fall over. Hence, you decide to check all the blueprints and see whether the constructions are stable or not.

Given is an up to 100 by 100 grid of characters in .#/_|-. The . characters denote empty space, while each other character represents a completely filled 1 × 1 box (any difference in symbols used is due to the artistic freedom of the other architects), whose center of mass is at the center of the box.

Every construction forms a single connected component that touches the ground, i.e. the bottom layer of the grid.

The construction falls to the left if the x-coordinate of the center of gravity is less than the x-coordinate of the leftmost point of the construction that touches the ground, and it falls to the right if the x-coordinate of the center of gravity is larger than the x-coordinate of the rightmost point of the construction that touches the ground. It is guaranteed that the center of gravity is never exactly above the leftmost or rightmost point where the building touches the ground.

Given a blueprint, is the construction balanced, does it fall to the left, or does it fall to the right?

输入

The first line has 1 ≤ h ≤ 100 and 1 ≤ w ≤ 100, the height and width of the grid.

Then follow h lines with l characters each. Each character is either ., indicating empty space, or one of #/_|-, indicating a filled 1 × 1 box .

输出

Print a single line containing left, balanced, or right.

样例输入

3 3

/-\

|.|

#.#

样例输出

balanced

#include <bits/stdc++.h>
 
using namespace std;
 
string ans1="balanced";
string ans2="left";
string ans3="right";
 
char e[111][111];
double pi[111];
int main () {
    int h,w;
    cin>>h>>w;
    string s;
    int m=0,cnt=0;
    for(int i=1;i<=h;i++) {
        cin>>s;
        int l=s.length ();
        for(int j=0;j<l;j++) {
            if(s[j]!='.') {
                m=m+j+1;
                cnt++;
            }
        }
    }
    double p=m*1.0/cnt;
    double x1=0,x2=0;
    for(int i=0;i<s.length ();i++) {
        if(s[i]!='.') {
            x1=i+1;
            break;
        }
    }
 
    for(int i=s.length ()-1;i>=0;i--) {
        if(s[i]!='.') {
            x2=i+1;
            break;
        }
    }
    x1=x1-0.5;
    x2=x2+0.5;
    if(p>x1&&p<x2) cout<<ans1<<endl;
    else if(p<x1) cout<<ans2<<endl;
    else cout<<ans3<<endl;
    return 0;
}

问题 K: Binary String

时间限制: 1 Sec 内存限制: 128 MB

提交 状态 题面

题目描述

A binary string is a non-empty sequence of 0’s and 1’s, e.g., 010110, 1, 11101, etc. Ayu has a favorite binary string S which contains no leading zeroes. She wants to convert S into its decimal representation with her calculator.

Unfortunately, her calculator cannot work on any integer larger than K and it will crash. Therefore, Ayu may need to remove zero or more bits from S while maintaining the order of the remaining bits such that its decimal representation is no larger than K. The resulting binary string also must not contain any leading zeroes.

Your task is to help Ayu to determine the minimum number of bits to be removed from S to satisfy Ayu’s need.

For example, let S = 1100101 and K = 13. Note that 1100101 is 101 in decimal representation, thus, we need to remove several bits from S to make it no larger than K. We can remove the 3rd, 5th, and 6th most significant bits, i.e. 1100101->1101. The decimal representation of 1101 is 13, which is no larger than K = 13. In this example, we removed 3 bits, and this is the minimum possible (If we remove only 2 bits,

then we will have a binary string of length 5 bits; notice that any binary string of length 5 bits has a value of at least 16 in decimal representation).

输入

Input begins with a line containing an integer K (1≤K≤260) representing the limit of Ayu’s calculator.

The second line contains a binary string S (1≤|S|≤60) representing Ayu’s favorite binary string. You may safely assume S contains no leading zeroes.

输出

Output contains an integer in a line representing the minimum number of bits to be removed from S.

样例输入

13

1100101

样例输出

3

提示

This sample is illustrated by the example given in the problem description above.

队友过的,听说挺简单的

#pragma GCC optimize(3,"Ofast","inline")
#include<bits/stdc++.h>

using namespace std;
typedef long long ll;
const int inf=0x3f3f3f3f;
const int N =105;
typedef pair<int,int>P;

ll k;
char s[N];
int lens,lenk,cnt0;

inline int getlen(ll x)
{
    int ans=0;
    while(x)
    {
        x>>=1;
        ans++;
    }
    return ans;
}

inline ll getsum()
{
    ll ret=0;
    for(int i=0;i<lens;i++)
    {
        if(s[i]=='1') ret+=(1ll<<(lens-1-i));
        else cnt0++;
    }
    return ret;
}
int main()
{
    //freopen("a.txt","r",stdin);
    scanf("%lld",&k);
    scanf("%s",s);
    lens=strlen(s);
    lenk=getlen(k);
    ll sn=getsum();
    //cout<<sn<<endl;
    //cout<<lenk<<' '<<lens<<endl;
    if(sn<=k)
    {
        puts("0");
        return 0;
    }
    ll temp=1ll<<(lenk-1);
    int cnt1=lenk-cnt0-1;
    int digit=0;
    for(int i=lens-1;i>0;i--)
    {
        if(cnt1<=0) break;
        if(s[i]=='1')
        {
            temp+=(1ll<<digit);
            cnt1--;
        }
        digit++;
    }
    //cout<<temp<<endl;
    if(temp<=k)  printf("%d\n",lens-lenk);
    else printf("%d\n",lens-lenk+1);
    return 0;
}

问题 J: Boomerangs

时间限制: 1 Sec 内存限制: 128 MB

提交 状态 题面

题目描述

Let G = (V,E) be a simple undirected graph with N vertices and M edges, where V = {1, …,N}. A tuple <u,v,w> is called as boomerang in G if and only if and u ≠ w, in other words, a boomerang consists of two edges which share a common vertex.

Given G, your task is to find as many disjoint boomerangs as possible in G. A set S contains disjoint boomerangs if and only if each edge in G only appears at most once (in one boomerang) in S. You may output any valid disjoint boomerangs, but the number of disjoint boomerangs should be maximum.

For example, consider a graph G = (V,E) of N = 5 vertices and M = 7 edges where E = [(1, 2), (1, 4),(2, 3), (2, 4), (2, 5), (3, 4), (3, 5)].

The maximum number of disjoint boomerangs in this example graph is 3. One example set containing the 3 disjoint boomerangs is [<4, 1, 2>, <4, 3, 2>, <2, 5, 3>], no set can contain more than 3 disjoint boomerangs in this example.

输入

Input begins with a line containing two integers: N M (1≤N,M≤100000), representing the number of vertices and the number edges in G, respectively. The next M lines, each contains two integers: ui vi(1≤ui < vi≤N), representing the edge (ui, vi) in G. You may safely assume that each edge appears at most once in the given list.

输出

Output contains an integer: K, representing the maximum number of disjoint boomerangs in G.

样例输入

5 7

1 2

1 4

2 3

2 4

2 5

3 4

3 5

样例输出

3

队友过的,不要想太复杂就可以了

#pragma GCC optimize(3,"Ofast","inline")
#include<bits/stdc++.h>

using namespace std;
typedef  long long ll;
const int N  = 200010;
typedef pair<int,int>P;
struct node
{
    int to,nex;
}grp[N];

int deg[N],head[N],cnt;
int n,m;
bool vis[N];
void add(int u,int v)
{
    grp[++cnt].to=v;
    grp[cnt].nex=head[u];
    head[u]=cnt;
    grp[++cnt].to=u;
    grp[cnt].nex=head[v];
    head[v]=cnt;
}

int dfs(int x,int nx)
{
    //cout<<x<<endl;
    if(vis[x]) return 0;
    vis[x]=true;
    int sum=0;
    for(int i=head[x];i;i=grp[i].nex)
    {
        int v=grp[i].to;
        sum++;
        sum+=dfs(v,x);
    }
    return sum;
}
int main()
{
    int ans=0;
    scanf("%d%d",&n,&m);
    for(int i=0;i<m;i++)
    {
        int u,v;
        scanf("%d%d",&u,&v);
        add(u,v);
    }
    for(int i=1;i<=n;i++)
    {
        if(!vis[i])
        {
            int sum=dfs(i,-1);
            //cout<<sum<<endl;
            ans+=(sum>>2);
        }
    }
    printf("%d\n",ans);
    return 0;
}

问题 I: Future Generation

时间限制: 1 Sec 内存限制: 128 MB

提交 状态 题面

题目描述

Andi is getting married! He and his partner plan to have N children. To avoid any hassle in the future, Andi wants to decide all their children’s name in advance. Specifically, he wants each child to have a name which is lexicographically larger than any of his/her older siblings. Of course, his partner also agrees with this idea. String A is lexicographically larger than string B if and only if B is a prefix of A or there exists an index i where Ai > Bi and Aj = Bj for all j < i. Note that a proper name can be as short as one character, but it cannot be an empty string.

Life is good for Andi, until one day he told his soon-to-be-grandmother-in-law (i.e. his partner’s grandma) about this marriage plan. After learning that Andi plans to have N children with her granddaughter, she gave him N names to be used. Moreover, the ith name can only be used for the ith child.

After going through a long debate with her grandma, Andi came into an agreement: The ith child’s name should be a subsequence of the ith name her grandma gave. A string A is a subsequence of string B if A can be obtained by deleting zero or more characters from B without changing the remaining characters’ order, e.g., ABC is a subsequence of DAEBCCB, but EFG is not a subsequence of FABEGC.

Even though Andi dislikes the given list of names, he still wants to impress his partner by showing that he can satisfy both her grandma’s wish and his own desire (i.e. each child’s name is lexicographically larger than any of his/her older siblings). However, Andi wonders, what is the maximum possible total length of their children names?

For example, let N = 3, and the names given by his partner’s grandma are (KARIM, PARBUDI,CHANDRA).

Here are several example set of names which satisfies Andi’s desire:

[AR, BI, CRA] with a total length of 2 + 2 + 3 = 7.

[ARI, BUDI, CHANDRA] with a total length of 3 + 4 + 7 = 14.

[ARIM, ARUDI, CHANDRA] with a total length of 4 + 5 + 7 = 16.

[AIM, ARBUDI,CHANDRA] with a total length of 3 + 6 + 7 = 16.

Among all sets of names which satisfy Andi’s desire in this example, the maximum total length is 16. Note that there might be cases where valid set of names cannot be obtained. In such case, you should output -1.

For example, let N = 2 and the names given by his partner’s grandma are (ZORO; ANDI). In this example, all subsequences of the 2nd name are lexicographically smaller than all subsequences of the 1st name, thus,no possible valid set of names can be obtained.

输入

Input begins with a line containing an integer N (1≤N≤15) representing the number of children. The next N lines, each contains a string Si (1≤|Si|≤15) representing the ith name given by Andi’s soon-tobe-grandmother-in-law. Si contains only uppercase alphabets (Sij ∈ A-Z).

输出

Output contains an integer in a line representing the maximum possible total length of their children names,or -1 if no possible valid set of names can be obtained.

样例输入

3

KARIM

PARBUDI

CHANDRA

样例输出

16

暴力DP

dp[i][j] i表示第i个序列,j表示第i个序列的第j大子序列

dp[i][j]=max(dp[i][j-1],dp[i-1][k]+string[i][j].size())

k表示i-1列,第一个大于[i][j]的子序列

#pragma GCC optimize(3,"Ofast","inline")
#include <stdio.h>
#include <iostream>
#include <algorithm>
#include <string.h>
#include <queue>
#include <vector>
#include <map>
#include <cmath>
#include <stack>
#include <set>
#include <algorithm>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
int n;
string s[20];
vector<string> ss[20];
int dp[20][(1<<15)+10];
int main()
{
    scanf("%d",&n);
    for(int i=1;i<=n;i++){
        cin>>s[i];
        //cout<<s[i]<<endl;
        int len = s[i].size();
        ss[i].push_back("");
        for(int j=0;j<len;j++){
            int lenlen=ss[i].size();
            for(int k=0;k<lenlen;k++){
                ss[i].push_back(ss[i][k]+s[i][j]);
                //cout<<"push"<<endl;
            }
        }
        sort(ss[i].begin(),ss[i].end());
    }
    memset(dp,-0x3f3f,sizeof(dp));
    //cout<<ss[1].size()<<endl;
    for(int i=1;i<ss[1].size();i++){
        dp[1][i]=max(dp[1][i-1],(int)ss[1][i].size());
        //cout<<dp[1][i]<<' '<<1<<' '<<i<<endl;
    }
    //cout<<n<<endl;
    for(int i=2;i<=n;i++){
        //cout<<i<<endl;
        int lenbe=ss[i-1].size();
        int lenno=ss[i].size();
        for(int j=1,k=0;j<lenno;j++){
            while(k<lenbe&&ss[i-1][k]<ss[i][j]) k++;
            dp[i][j]=max(dp[i][j-1],dp[i-1][k-1]+(int)ss[i][j].size());
            //cout<<dp[i][j]<<' '<<i<<' '<<j<<endl;
        }
    }
    int ans=dp[n][ss[n].size()-1];
    if(ans<0) cout<<"-1"<<endl;
    else cout<<ans<<endl;
    return 0;
}

问题 H: Lie Detector

时间限制: 1 Sec 内存限制: 128 MB

提交 状态 题面

题目描述

Andi is a young and prominent detective in the police force. His ability to track down criminals, uncover the truth, and solve cases never ceases to amaze all of his colleagues. One day, he is faced with a suspicious eyewitness testimony when working on a certain case. In usual cases, Andi simply ignores such unreliable testimony; however, in this case, the eyewitness testimony is too important to be ignored. To resolve this situation, Andi has to rely on technology, i.e. using a lie detector.

Andi proceeds to use a lie detector to detect whether the eyewitness testimony is true. However, Andi notices that the lie detector he used might have been tampered, thus, he employs a second lie detector to detect whether the first lie detector’s result is correct. This situation happens repeatedly such that Andi ends up employing N lie detectors in total. The ith lie detector reports the truth of the (i-1)th lie detector for i = 2..N,and the 1st lie detector reports the truth of the eyewitness testimony.

In the end, Andi knows that the last (Nth) lie detector has not been tampered and always report the truth correctly. Now, he needs to determine whether the eyewitness testimony is true given the result of all lie detectors.

For example, let N = 4 and the lie detectors result are (LIE, LIE,TRUTH,TRUTH).

The 4th lie detector reports that the 3rd lie detector is TRUTH. As the 4th lie detector always report the truth correctly, then the 3rd lie detector’s result is correct as it is.

The 3rd lie detector reports that the 2nd lie detector is TRUTH. As the 3rd lie detector’s result is correct as it is, then the 2nd lie detector’s result is also correct as it is.

The 2nd lie detector reports that the 1st lie detector is LIE. As the 2nd lie detector’s result is correct as it is, then the 1st lie detector’s result is wrong.

The 1st lie detector reports that the eyewitness testimony is LIE. As the 1st lie detector’s result is wrong, then the eyewitness testimony is correct; in other words, what the eyewitness says is true.

Therefore, the eyewitness testimony in this example is true.

输入

Input begins with a line containing an integer N (2≤N≤100000). The next N lines, each contains a string Si (either TRUTH or LIE) representing the output of the ith lie detector for i = 1..N respectively.

输出

Output contains a string TRUTH or LIE in a line whether the eyewitness testimony is true or false.

样例输入

4

LIE

LIE

TRUTH

TRUTH

样例输出

TRUTH

大水题

#pragma GCC optimize(3,"Ofast","inline")
#include <stdio.h>
#include <iostream>
#include <algorithm>
#include <string.h>
#include <queue>
#include <vector>
#include <map>
#include <cmath>
#include <stack>
#include <set>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
 
bool check(bool a,bool b){
    if(a&&b) return true;
    if(a&&!b) return false;
    if(!a&&b) return false;
    return true;
}
char tmp[1000];
bool ans[100010];
int main()
{
    int _;
    scanf("%d",&_);
    for(int i=0;i<_;i++){
        scanf("%s",tmp);
        if(tmp[0]=='T') ans[i]=true;
        else ans[i]=false;
    }
    for(int i=_-2;i>=0;i--){
        ans[i]=check(ans[i],ans[i+1]);
    }
    if(ans[0]) cout<<"TRUTH"<<endl;
    else cout<<"LIE"<<endl;
    return 0;
}

通过 WordPress.com 设计一个这样的站点
从这里开始