ACM/ICPC 2018亚洲区预选赛北京赛站网络赛

菜鸡只配拥有三题,难过

题目1 : Saving Tang Monk II

时间限制:1000ms
单点时限:1000ms
内存限制:256MB

描述

《Journey to the West》(also 《Monkey》) is one of the Four Great Classical Novels of Chinese literature. It was written by Wu Cheng'en during the Ming Dynasty. In this novel, Monkey King Sun Wukong, pig Zhu Bajie and Sha Wujing, escorted Tang Monk to India to get sacred Buddhism texts.

During the journey, Tang Monk was often captured by demons. Most of demons wanted to eat Tang Monk to achieve immortality, but some female demons just wanted to marry him because he was handsome. So, fighting demons and saving Monk Tang is the major job for Sun Wukong to do.

Once, Tang Monk was captured by the demon White Bones. White Bones lived in a palace and she cuffed Tang Monk in a room. Sun Wukong managed to get into the palace, and he wanted to reach Tang Monk and rescue him.

The palace can be described as a matrix of characters. Different characters stand for different rooms as below:

'S' : The original position of Sun Wukong

'T' : The location of Tang Monk

'.' : An empty room

'#' : A deadly gas room.

'B' : A room with unlimited number of oxygen bottles. Every time Sun Wukong entered a 'B' room from other rooms, he would get an oxygen bottle. But staying there would not get Sun Wukong more oxygen bottles. Sun Wukong could carry at most 5 oxygen bottles at the same time.

'P' : A room with unlimited number of speed-up pills. Every time Sun Wukong entered a 'P' room from other rooms, he would get a speed-up pill. But staying there would not get Sun Wukong more speed-up pills. Sun Wukong could bring unlimited number of speed-up pills with him.

Sun Wukong could move in the palace. For each move, Sun Wukong might go to the adjacent rooms in 4 directions(north, west,south and east). But Sun Wukong couldn't get into a '#' room(deadly gas room) without an oxygen bottle. Entering a '#' room each time would cost Sun Wukong one oxygen bottle.

Each move took Sun Wukong one minute. But if Sun Wukong ate a speed-up pill, he could make next move without spending any time. In other words, each speed-up pill could save Sun Wukong one minute. And if Sun Wukong went into a '#' room, he had to stay there for one extra minute to recover his health.

Since Sun Wukong was an impatient monkey, he wanted to save Tang Monk as soon as possible. Please figure out the minimum time Sun Wukong needed to reach Tang Monk.

输入

There are no more than 25 test cases.

For each case, the first line includes two integers N and M(0 < N,M ≤ 100), meaning that the palace is a N × M matrix.

Then the N×M matrix follows.

The input ends with N = 0 and M = 0.

输出

For each test case, print the minimum time (in minute) Sun Wukong needed to save Tang Monk. If it's impossible for Sun Wukong to complete the mission, print -1

样例输入
2 2
S#
#T
2 5
SB###
##P#T
4 7
SP.....
P#.....
......#
B...##T
0 0
样例输出
-1
8
11

这个A就是有一个氧气和加速,所以你把情况展开,分别讨论氧气和加速

#include<bits/stdc++.h>
using namespace std;

int vis[105][105][10];//N,M,氧气
char G[105][105];
int n,m;
struct node
{
    int x,y,ox,pill,k;
    node(){}
    node(int x,int y,int ox,int pill,int k):x(x),y(y),ox(ox),pill(pill),k(k){}
}s,en;
int dx[]={0,0,1,-1};
int dy[]={1,-1,0,0};

int bfs()
{
    node t;
    queue<node>q;
    q.push(s);
    vis[s.x][s.y][0]=true;
    int minn=0x3f3f3f3f;
    while(!q.empty())
    {
        node h=q.front();q.pop();
        //printf("x=%d y=%d ox=%d pill=%d k=%d\n",h.x,h.y,h.ox,h.pill,h.k);
        //if(h.x==en.x&&h.y==en.y)minn=min(minn,h.k);
        for(int i=0;i<4;i++)
        {
            t.x=h.x+dx[i];
            t.y=h.y+dy[i];
            t.k=h.k+1;
            if(t.x>=0&&t.x<n&&t.y>=0&&t.y<m)
            {
                if(G[t.x][t.y]=='.')
                {
                    if(h.pill>=1&&vis[t.x][t.y][h.ox]>t.k-1)
                        q.push({t.x,t.y,h.ox,h.pill-1,vis[t.x][t.y][h.ox]=t.k-1});
                    else if(h.pill<1&&vis[t.x][t.y][h.ox]>t.k)
                        q.push({t.x,t.y,h.ox,h.pill,vis[t.x][t.y][h.ox]=t.k});
                }
                else if(G[t.x][t.y]=='#'&&h.ox>0)
                {
                    if(h.pill>=1&&vis[t.x][t.y][h.ox-1]>t.k)
                        q.push({t.x,t.y,h.ox-1,h.pill-1,vis[t.x][t.y][h.ox-1]=t.k});
                    else if(h.pill<1&&vis[t.x][t.y][h.ox-1]>t.k+1)
                        q.push({t.x,t.y,h.ox-1,h.pill,vis[t.x][t.y][h.ox-1]=t.k+1});
                }
                else if(G[t.x][t.y]=='B'&&h.ox<=5)
                {
                    if(h.ox<=4)
                    {
                        if(h.pill>=1&&vis[t.x][t.y][h.ox+1]>t.k-1)
                            q.push({t.x,t.y,h.ox+1,h.pill-1,vis[t.x][t.y][h.ox+1]=t.k-1});
                        else if(h.pill<1&&vis[t.x][t.y][h.ox+1]>t.k)
                            q.push({t.x,t.y,h.ox+1,h.pill,vis[t.x][t.y][h.ox+1]=t.k});
                    }
                    else if(h.ox==5)
                    {
                        if(h.pill>=1&&vis[t.x][t.y][h.ox]>t.k-1)
                            q.push({t.x,t.y,h.ox,h.pill-1,vis[t.x][t.y][h.ox]=t.k-1});
                        else if(h.pill<1&&vis[t.x][t.y][h.ox]>t.k)
                            q.push({t.x,t.y,h.ox,h.pill,vis[t.x][t.y][h.ox]=t.k});
                    }
                }
                else if(G[t.x][t.y]=='P')
                {
                    if(h.pill>=1&&vis[t.x][t.y][h.ox]>t.k-1)
                        q.push({t.x,t.y,h.ox,h.pill,vis[t.x][t.y][h.ox]=t.k-1});
                    else if(h.pill<1&&vis[t.x][t.y][h.ox]>t.k)
                        q.push({t.x,t.y,h.ox,h.pill+1,vis[t.x][t.y][h.ox]=t.k});
                }
                else if(G[t.x][t.y]=='S')
                {
                    if(h.pill>=1&&vis[t.x][t.y][h.ox]>t.k-1)
                        q.push({t.x,t.y,h.ox,h.pill-1,t.k-1});
                    else if(h.pill<1&&vis[t.x][t.y][h.ox]>t.k)
                        q.push({t.x,t.y,h.ox,h.pill,t.k});
                }
                else if(G[t.x][t.y]=='T')
                {
                    if(h.pill>0)
                        minn=min(minn,t.k-1);
                    else
                        minn=min(minn,t.k);
                }
            }
        }
    }
    if(minn==0x3f3f3f3f)return -1;
    else return minn;
}
int solve()
{
    int flagS=0,flagT=0;
    for(int i=0;i<n;i++)
        for(int j=0;j<m;j++)
            if(G[i][j]=='S')
            {
                flagS++;
                s.x=i,s.y=j,s.ox=0,s.pill=0,s.k=0;
            }
            else if(G[i][j]=='T')
            {
                flagT++;
                en.x=i,en.y=j;
            }
    if(flagS==1&&flagT==1)return bfs();
    else return -1;
}
int main()
{
    srand(time(NULL));
    while(scanf("%d%d",&n,&m)!=EOF,n||m)
    {
        /*
        for(int i=0;i<n;i++)
            for(int j=0;j<m;j++)
            {
                int c=rand()%4;
                if(c==0)G[i][j]='#';
                if(c==1)G[i][j]='B';
                if(c==2)G[i][j]='.';
                if(c==3)G[i][j]='P';
            }
        G[1][2]='S';
        G[5][6]='T';
        for(int i=0;i<n;i++)
            G[i][m]='\0';
        for(int i=0;i<n;i++)
            printf("%s\n",G[i]);
        */
        memset(vis,0x3f3f3f3f,sizeof vis);
        
        for(int i=0;i<n;i++)
            scanf("%s",G[i]);
        
        printf("%d\n",solve());
    }
    return 0;
}
/*
5 5
S.BP.
BBBPB
P#BBB
..BB.
P#P#T
*/
/*
4 7
SP...P.
P##B###
.#....P
B...##T
5 7
S#...#T
.#.#.##
.#.#.##
.#.#.##
B..#.##
*/

#1835 : K-Dimensional Foil II

时间限制:1000ms
单点时限:1000ms
内存限制:256MB

描述

"K-Dimensional Foil" is a dimensional weapon. Its function is quite easy: It can ascend a region in 3D space to K (K≥3) dimension. One can use it to give the enemy unexpected attack. It was called "The Ultimate Weapon".

--"Remembrance of Mars's Past"

You are the chief technology officer in the space fleet, and your fleet was just suffered from the attack of the K-Dimensional Foil. The good news was that you have found the key parameter K, the dimension of the space. But staying in high dimensional space is very dangerous, you must destroy the K-Dimensional Foil as fast as possible.

You have n spaceships, spaceship i locates at si = (si,1, …, si,K), and the K-Dimensional  Foil is a 1-norm ball with center c = (c1, …, cK) and radius r, a 1-norm ball with center c and radius r is a point set defined as
{x |  d(x, c)  ≤ r}, d(x, c) =∑| xi - ci |

In the formula above, the coordinate of point x is (x1, x2 … xK)

Your spaceships will fire laser cannon to destroy the K-Dimensional Foil. The energy decay is very quick with the increase of the distance in the high dimensional space, so for every spaceship, you want to find the closest point (in Euclidean distance) on the K-Dimensional Foil. It's guaranteed that no spaceship is in the K-Dimensional Foil initially.

输入

The first line of the input is an integer T (T ≤ 100), the number of the test cases.

For each test case, the first line contains two integer nK (1 ≤ n ≤ 50, 1 ≤ K ≤ 100), the number of spaceship in your fleet and the dimension of the space.

Then one line contains an integer r (1 ≤ r ≤ 104 ), the radius of the K-Dimensional Foil.

Then one line contains K integers c1, … cK, meaning the coordinate of the center of the K-Dimensional Foil.

Then n lines follow. Each line contains K integers si,1, …, si,K, meaning the coordinate of a spaceship.

All the absolute values of the coordinate are smaller than 104.

输出

For each test case, output n lines. The ith line contains K numbers representing the coordinate of the closest point on the K-Dimensional Foil to the ith spaceship. The absolute error between your output and the answer should be less than 10-4

提示

The K-Dimensional Foil in the sample was a square with vertex: (1,0), (0,1), (-1,0), (0,-1)

This problem is special judged.

样例输入
1
2 2
1
0 0
1 1
1 3
样例输出
0.50 0.50
0.00 1.00
最后求偏导就汇发现是个符号的问题了
#include<bits/stdc++.h>
using namespace std;
const int N=105;
int c[N],s[N],p[N],sgn[N];
int main()
{
    int T;
    scanf("%d",&T);
    while(T--)
    {
        int n,k,r;
        scanf("%d%d%d",&n,&k,&r);
        for(int i=0;i<k;i++)
            scanf("%d",&c[i]);
        while(n--)
        {
            for(int i=0;i<k;i++)
                scanf("%d",&s[i]);
            for(int i=0;i<k;i++)
                s[i]-=c[i],sgn[i]=(s[i]>=0 ? 1 : -1),s[i]=abs(s[i]);
            int now=-r;
            for(int i=0;i<k;i++)
                now+=s[i],p[i]=1;
            int dim=k;
            while(1)
            {
                bool cha=0;
                for(int i=0;i<k;i++)
                    if(p[i] && s[i]*dim<now)
                    {
                        now-=s[i];
                        dim--;
                        s[i]=p[i]=0;
                        cha=1;
                    }
                if(!cha)break;
            }
            for(int i=0;i<k;i++)
                printf("%.6f%c",p[i]*(s[i]-1.0*now/dim)*sgn[i]+c[i]," \n"[i==k-1]);
        }
    }
    return 0;
}

题目2 : Tomb Raider

时间限制:1000ms
单点时限:1000ms
内存限制:256MB

描述

Lara Croft, the fiercely independent daughter of a missing adventurer, must push herself beyond her limits when she discovers the island where her father disappeared. In this mysterious island, Lara finds a tomb with a very heavy door. To open the door, Lara must input the password at the stone keyboard on the door. But what is the password? After reading the research notes written in her father's notebook, Lara finds out that the key is on the statue beside the door.

The statue is wearing many arm rings on which some letters are carved. So there is a string on each ring. Because the letters are carved on a circle and the spaces between any adjacent letters are all equal, any letter can be the starting letter of the string. The longest common subsequence (let's call it "LCS") of the strings on all rings is the password. A subsequence is a sequence that can be derived from another sequence by deleting some or no elements without changing the order of the remaining elements.

For example, there are two strings on two arm rings: s1 = "abcdefg" and s2 = "zaxcdkgb". Then "acdg" is a LCS if you consider 'a' as the starting letter of s1, and consider 'z' or 'a' as the starting letter of s2. But if you consider 'd' as the starting letter of s1 and s2, you can get "dgac" as a LCS. If there are more than one LCS, the password is the one which is the smallest in lexicographical order.

Please find the password for Lara.

输入

There are no more than 10 test cases.

In each case:

The first line is an integer n, meaning there are n (0 < n ≤ 10) arm rings.

Then n lines follow. Each line is a string on an arm ring consisting of only lowercase letters. The length of the string is no more than 8.

输出

For each case, print the password. If there is no LCS, print 0 instead.

样例输入
2
abcdefg
zaxcdkgb
5
abcdef
kedajceu
adbac
abcdef
abcdafc
2
abc
def
样例输出
acdg
acd
0

这个题说是所有的LCS,但是你可以枚举第一个串的子串啊,然后每个暴力判断一下就好

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
string s[15],tmp[300];
int l[300],cnt;
void dfs(int pos,string y)
{
    if(pos==s[0].size()) 
    {
        tmp[cnt++]=y;
        return;
    }
    dfs(pos+1,y);
    dfs(pos+1,y+s[0][pos]);
}
ll calc(int x)
{
    ll ans=1;
    for(int i=1;i<=x;i++)
        ans*=26;
    return ans;
}
bool check(string a,string b)
{
    int strlena=a.size(),strlenb=b.size();
    for(int i=0;i<strlenb;i++)
    {
        int pos=0,j=i;
        while(pos<strlena&&j<i+strlenb)
        {
            while(a[pos]==b[j]&&pos<strlena) pos++,j++;
            j++;
        }
        if(pos==strlena) return true;
        b+=b[i];
    }
    return false;
}
int main()
{
    int n;
    while(cin>>n)
    {
        for(int i=0;i<n;i++) cin>>s[i];
        cnt=0;
        dfs(0,"");
        for(int i=1;i<cnt;i++)
        {
            l[i]=tmp[i].size();
            ll ans=0,pos=0,maxx;
            for(int j=0;j<l[i];j++)
                ans*=26,ans+=tmp[i][j]-'a';
            maxx=ans;
            for(int j=1;j<l[i];j++)
            {
                int x=calc(l[i]-1);
                ans%=x;
                ans*=26;
                ans+=tmp[i][j-1]-'a';
                if(ans<maxx)
                {
                    maxx=ans;
                    pos=j;
                }
            }
            string ss=tmp[i].substr(pos,l[i]-pos);
            tmp[i].erase(pos,l[i]-pos);
            tmp[i]=ss+tmp[i];
        }
        for(int i=1;i<cnt;i++)
            for(int j=i+1;j<cnt;j++)
                if(l[i]<l[j]) swap(tmp[i],tmp[j]),swap(l[i],l[j]);
                else if(l[i]==l[j]&&tmp[i]>tmp[j]) swap(tmp[i],tmp[j]),swap(l[i],l[j]);
        string ans="0";
        for(int i=1;i<cnt;i++)
        {
            bool f=1;
            for(int j=1;j<n;j++)
            {
                f=check(tmp[i],s[j]);
                if(!f) break;
            }
            if(f) {ans=tmp[i];break;}
        }
        cout<<ans<<'\n';
    }
    return 0;
}

题目4 : 80 Days

时间限制:1000ms
单点时限:1000ms
内存限制:256MB

描述

80 Days is an interesting game based on Jules Verne's science fiction "Around the World in Eighty Days". In this game, you have to manage the limited money and time.

Now we simplified the game as below:

There are n cities on a circle around the world which are numbered from 1 to n by their order on the circle. When you reach the city i at the first time, you will get ai dollars (ai can even be negative), and if you want to go to the next city on the circle, you should pay bi dollars. At the beginning you have c dollars.

The goal of this game is to choose a city as start point, then go along the circle and visit all the city once, and finally return to the start point. During the trip, the money you have must be no less than zero.

Here comes a question: to complete the trip, which city will you choose to be the start city?

If there are multiple answers, please output the one with the smallest number.

输入

The first line of the input is an integer T (T ≤ 100), the number of test cases.

For each test case, the first line contains two integers n and c (1 ≤ n ≤ 106, 0 ≤ c ≤ 109).  The second line contains n integers a1, …, an  (-10≤ a≤ 109), and the third line contains n integers b1, …, bn (0 ≤ b≤ 109).

It's guaranteed that the sum of n of all test cases is less than 106

输出

For each test case, output the start city you should choose.

提示

For test case 1, both city 2 and 3 could be chosen as start point, 2 has smaller number. But if you start at city 1, you can't go anywhere.

For test case 2, start from which city seems doesn't matter, you just don't have enough money to complete a trip.

样例输入
2
3 0
3 4 5
5 4 3
3 100
-3 -4 -5
30 40 50
样例输出
2
-1

这个题目需要尺取,去枚举从l开始是否合法

#include <bits/stdc++.h>
using namespace std;
const int N=1000005;
int p[N<<1],a[N],b[N];
int main()
{
    int T,n,c;
    scanf("%d",&T);
    while(T--)
    {
        scanf("%d%d",&n,&c);
        for(int i=1;i<=n;i++) scanf("%d",&a[i]);
        for(int i=1;i<=n;i++) scanf("%d",&b[i]);
        for(int i=1;i<=n;i++)
            p[i]=p[i+n]=a[i]-b[i];
        int l=1,r=1;
        long long num=0;
        while(l<=n&&r-l+1<=n)
        {
            num+=p[r++];
            while(num+c<0) num-=p[l++];
        }
        printf("%d\n",l>n?-1:l);
    }
    return 0;
}
posted @ 2018-09-22 21:21  暴力都不会的蒟蒻  阅读(1069)  评论(0编辑  收藏  举报