【第22期】观点:IT 行业加班,到底有没有价值?

2014上海全国邀请赛(hdu 5090 - 5099)dp+线段树+拓扑排序+bfs(状态压缩)

原创 2015年07月10日 10:12:43

Game with Pearls
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 1431 Accepted Submission(s): 527

Problem Description
Tom and Jerry are playing a game with tubes and pearls. The rule of the game is:

1) Tom and Jerry come up together with a number K.

2) Tom provides N tubes. Within each tube, there are several pearls. The number of pearls in each tube is at least 1 and at most N.

3) Jerry puts some more pearls into each tube. The number of pearls put into each tube has to be either 0 or a positive multiple of K. After that Jerry organizes these tubes in the order that the first tube has exact one pearl, the 2nd tube has exact 2 pearls, …, the Nth tube has exact N pearls.

4) If Jerry succeeds, he wins the game, otherwise Tom wins.

Write a program to determine who wins the game according to a given N, K and initial number of pearls in each tube. If Tom wins the game, output “Tom”, otherwise, output “Jerry”.

Input
The first line contains an integer M (M<=500), then M games follow. For each game, the first line contains 2 integers, N and K (1 <= N <= 100, 1 <= K <= N), and the second line contains N integers presenting the number of pearls in each tube.

Output
For each game, output a line containing either “Tom” or “Jerry”.

Sample Input

2
5 1
1 2 3 4 5
6 2
1 2 3 4 5 5

Sample Output

Jerry
Tom

题意:有n个盒子,每个盒子初始有1-n个球,现在要在盒子里添加k的倍数个球,使得最后盒子排序后,第一个盒子有1个球,第n个盒子有n个球
思路:暴力,1-n每个数字是由谁得来的,只要有一个就可以,如果有多个,那么如果满足题意条件,剩下的也必然能转化成其他的

#include<iostream>
#include<cstdio>
#include<string>
#include<cstring>
#include<vector>
#include<cmath>
#include<queue>
#include<stack>
#include<map>
#include<set>
#include<algorithm>
using namespace std;
const int maxn=510;
int a[maxn];
int N,K;
int main()
{
    int T;
    scanf("%d",&T);
    while(T--)
    {
        scanf("%d%d",&N,&K);
        memset(a,0,sizeof(a));
        for(int i=1;i<=N;i++)
        {
            int x;
            scanf("%d",&x);
            a[x]++;
        }
        bool flag=true;
        for(int i=1;i<=N;i++)
        {
            bool flag1=false;
            for(int j=0;i-K*j>=0;j++)
            {
                if(a[i-K*j])
                {
                    flag1=true;
                    a[i-j*K]--;
                    break;
                }
            }
            if(!flag1){flag=false;break;}
        }
        if(flag)printf("Jerry\n");
        else printf("Tom\n");
    }
    return 0;
}

Beam Cannon
Time Limit: 3000/1500 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 644 Accepted Submission(s): 234

Problem Description
Recently, the γ galaxies broke out Star Wars. Each planet is warring for resources. In the Star Wars, Planet X is under attack by other planets. Now, a large wave of enemy spaceships is approaching. There is a very large Beam Cannon on the Planet X, and it is very powerful, which can destroy all the spaceships in its attack range in a second. However, it takes a long time to fill the energy of the Beam Cannon after each shot. So, you should make sure each shot can destroy the enemy spaceships as many as possible.

To simplify the problem, the Beam Cannon can shot at any area in the space, and the attack area is rectangular. The rectangle parallels to the coordinate axes and cannot rotate. It can only move horizontally or vertically. The enemy spaceship in the space can be considered as a point projected to the attack plane. If the point is in the rectangular attack area of the Beam Cannon(including border), the spaceship will be destroyed.

Input
Input contains multiple test cases. Each test case contains three integers N(1<=N<=10000, the number of enemy spaceships), W(1<=W<=40000, the width of the Beam Cannon’s attack area), H(1<=H<=40000, the height of the Beam Cannon’s attack area) in the first line, and then N lines follow. Each line contains two integers x,y (-20000<=x,y<=20000, the coordinates of an enemy spaceship).

A test case starting with a negative integer terminates the input and this test case should not to be processed.

Output
Output the maximum number of enemy spaceships the Beam Cannon can destroy in a single shot for each case.

Sample Input

2 3 4
0 1
1 0
3 1 1
-1 0
0 1
1 0
-1

Sample Output

2
2

题意:有n个星星,一个W*H的框,问最多能框住多少星星
思路:线段树扫描线,将每个点抽象成两条线段,我是按y轴方向扫的,这样做的原因是每个点的影响范围有限,见下图。
这里写图片描述
图中A点可以影响到的矩形是(x,x+W)范围内的,A点抽象成了1,-1这两条线,也就是说明,他纵向能影响到的是这个范围。

#include<iostream>
#include<cstdio>
#include<string>
#include<cstring>
#include<vector>
#include<cmath>
#include<queue>
#include<stack>
#include<map>
#include<set>
#include<algorithm>
using namespace std;
const int maxn=40010;
const int BIT=20000;
int N,W,H;
struct Segment
{
    int l,r,h,t;
    Segment()=default;
    Segment(int a,int b,int c,int d):l(a),r(b),h(c),t(d){}
    bool operator<(const Segment &a)const
    {
        return h<a.h;
    }
}s[maxn];
struct IntervalTree
{
    int sum[maxn<<2];
    int setv[maxn<<2];
    void build(int o,int l,int r)
    {
        sum[o]=setv[o]=0;
        if(l==r)return ;
        int mid=(l+r)>>1;
        build(o<<1,l,mid);
        build(o<<1|1,mid+1,r);
    }
    void  pushdown(int o)
    {
        if(setv[o])
        {
            setv[o<<1]+=setv[o];
            setv[o<<1|1]+=setv[o];
            sum[o<<1]+=setv[o];
            sum[o<<1|1]+=setv[o];
            setv[o]=0;
        }
    }
    void pushup(int o)
    {
        sum[o]=max(sum[o<<1],sum[o<<1|1]);
    }
    void update(int o,int l,int r,int q1,int q2,int x)
    {
        if(q1<=l&&r<=q2)
        {
            sum[o]+=x;
            setv[o]+=x;
            return ;
        }
        pushdown(o);
        int mid=(l+r)>>1;
        if(q1<=mid)update(o<<1,l,mid,q1,q2,x);
        if(q2>mid)update(o<<1|1,mid+1,r,q1,q2,x);
        pushup(o);
    }
}tree;
int main()
{
    while(scanf("%d",&N)!=EOF,N>0)
    {
        scanf("%d%d",&W,&H);
        int num=0;
        for(int i=0;i<N;i++)
        {
            int x,y;
            scanf("%d%d",&x,&y);
            x+=BIT,y+=BIT;
            int lx=(x+W>40000?40000:x+W);
            s[num++]=Segment(x,lx,y,1);
            s[num++]=Segment(x,lx,y+H,-1);
        }
        int ans=0;
        sort(s,s+num);
        tree.build(1,0,40000);
        for(int i=0;i<num;i++)
        {
            tree.update(1,0,40000,s[i].l,s[i].r,s[i].t);
            ans=max(ans,tree.sum[1]);
        }
        printf("%d\n",ans);
    }
    return 0;
}

Seam Carving
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 797 Accepted Submission(s): 323

Problem Description
Fish likes to take photo with his friends. Several days ago, he found that some pictures of him were damaged. The trouble is that there are some seams across the pictures. So he tried to repair these pictures. He scanned these pictures and stored them in his computer. He knew it is an effective way to carve the seams of the images He only knew that there is optical energy in every pixel. He learns the following principle of seam carving. Here seam carving refers to delete through horizontal or vertical line of pixels across the whole image to achieve image scaling effect. In order to maintain the characteristics of the image pixels to delete the importance of the image lines must be weakest. The importance of the pixel lines is determined in accordance with the type of scene images of different energy content. That is, the place with the more energy and the richer texture of the image should be retained. So the horizontal and vertical lines having the lowest energy are the object of inspection. By constantly deleting the low-energy line it can repair the image as the original scene.

这里写图片描述
For an original image G of m*n, where m and n are the row and column of the image respectively. Fish obtained the corresponding energy matrix A. He knew every time a seam with the lowest energy should be carved. That is, the line with the lowest sum of energy passing through the pixels along the line, which is a 8-connected path vertically or horizontally.

Here your task is to carve a pixel from the first row to the final row along the seam. We call such seam a vertical seam.

Input
There several test cases. The first line of the input is an integer T, which is the number of test cases, 0

#include<iostream>
#include<cstdio>
#include<string>
#include<cstring>
#include<vector>
#include<cmath>
#include<queue>
#include<stack>
#include<map>
#include<set>
#include<algorithm>
using namespace std;
const int maxn=110;
const int INF=0x3f3f3f3f;
int N,M;
int dp[maxn][maxn];
int a[maxn][maxn];
int path[maxn][maxn];

int main()
{
    int T,cas=1;
    scanf("%d",&T);
    while(T--)
    {
        scanf("%d%d",&N,&M);
        for(int i=1;i<=N;i++)
            for(int j=1;j<=M;j++)scanf("%d",&a[i][j]);
        memset(dp,INF,sizeof(dp));
        memset(path,-1,sizeof(path));
        for(int i=1;i<=M;i++)dp[N][i]=a[N][i];
        for(int i=N-1;i>=1;i--)
        {
            for(int j=1;j<=M;j++)
            {
                dp[i][j]=dp[i+1][j]+a[i][j];
                path[i][j]=j;
                if(j-1>0&&dp[i+1][j-1]+a[i][j]<dp[i][j])
                {
                    dp[i][j]=dp[i+1][j-1]+a[i][j];
                    path[i][j]=j-1;
                }
                if(j+1<=M&&dp[i+1][j+1]+a[i][j]<=dp[i][j])
                {
                    dp[i][j]=dp[i+1][j+1]+a[i][j];
                    path[i][j]=j+1;
                }
            }
        }
        int ans,maxv=INF;
        for(int i=1;i<=M;i++)
            if(dp[1][i]<=maxv)maxv=dp[1][i],ans=i;
        bool first=true;
        printf("Case %d\n",cas++);
        for(int i=1;i<=N;i++)
        {
            printf("%d",ans);
            if(i!=N)printf(" ");
            else printf("\n");
            ans=path[i][ans];
        }
    }
    return 0;
}

Maze
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 100000/100000 K (Java/Others)
Total Submission(s): 763 Accepted Submission(s): 273

Problem Description
This story happened on the background of Star Trek.

Spock, the deputy captain of Starship Enterprise, fell into Klingon’s trick and was held as prisoner on their mother planet Qo’noS.

The captain of Enterprise, James T. Kirk, had to fly to Qo’noS to rescue his deputy. Fortunately, he stole a map of the maze where Spock was put in exactly.

The maze is a rectangle, which has n rows vertically and m columns horizontally, in another words, that it is divided into n*m locations. An ordered pair (Row No., Column No.) represents a location in the maze. Kirk moves from current location to next costs 1 second. And he is able to move to next location if and only if:

Next location is adjacent to current Kirk’s location on up or down or left or right(4 directions)
Open door is passable, but locked door is not.
Kirk cannot pass a wall

There are p types of doors which are locked by default. A key is only capable of opening the same type of doors. Kirk has to get the key before opening corresponding doors, which wastes little time.

Initial location of Kirk was (1, 1) while Spock was on location of (n, m). Your task is to help Kirk find Spock as soon as possible.

Input
The input contains many test cases.

Each test case consists of several lines. Three integers are in the first line, which represent n, m and p respectively (1<= n, m <=50, 0<= p <=10).
Only one integer k is listed in the second line, means the sum number of gates and walls, (0<= k <=500).

There are 5 integers in the following k lines, represents xi1, yi1, xi2, yi2, gi; when gi >=1, represents there is a gate of type gi between location (xi1, yi1) and (xi2, yi2); when gi = 0, represents there is a wall between location (xi1, yi1) and (xi2, yi2), ( | xi1 - xi2 | + | yi1 - yi2 |=1, 0<= gi <=p )

Following line is an integer S, represent the total number of keys in maze. (0<= S <=50).

There are three integers in the following S lines, represents xi1, yi1 and qi respectively. That means the key type of qi locates on location (xi1, yi1), (1<= qi<=p).

Output
Output the possible minimal second that Kirk could reach Spock.

If there is no possible plan, output -1.

Sample Input

4 4 9
9
1 2 1 3 2
1 2 2 2 0
2 1 2 2 0
2 1 3 1 0
2 3 3 3 0
2 4 3 4 1
3 2 3 3 0
3 3 4 3 0
4 3 4 4 0
2
2 1 2
4 2 1

Sample Output

14

题意:有一个迷宫,格子之间有门或墙,有p种门,S个钥匙,问从(1,1)走到(n,m)最短时间
思路:还是普通的bfs,只不过是加一个状态,保存当前有哪些钥匙

#include<iostream>
#include<cstdio>
#include<string>
#include<cstring>
#include<vector>
#include<cmath>
#include<queue>
#include<stack>
#include<map>
#include<set>
#include<algorithm>
using namespace std;
const int maxn=55;
int N,M,P,K,S;
struct node
{
    int x,y,t;
    int S;
    node()=default;
    node(int a,int b,int c,int d):x(a),y(b),t(c),S(d){}
};
int gate[maxn][maxn][maxn][maxn];
int key[maxn][maxn];
bool vis[maxn][maxn][1<<11];
int dx[]={0,0,1,-1};
int dy[]={1,-1,0,0};
int BFS(int sx,int sy)
{
    memset(vis,0,sizeof(vis));
    queue<node> q;
    node B;
    if(key[sx][sy])
        q.push(node(sx,sy,0,key[sx][sy]));
    else q.push(node(sx,sy,0,0));
    while(!q.empty())
    {
        node A=q.front();q.pop();
        for(int i=0;i<4;i++)
        {
            int tx=A.x+dx[i];
            int ty=A.y+dy[i];
            if(tx<1||tx>N||ty<1||ty>M)continue;
            int g=gate[A.x][A.y][tx][ty];
            if(g==0)continue;
            if(g>0)
            {
                if(!(A.S&(1<<(g-1))))
                    continue;
            }
            int tmpS=A.S;
            if(key[tx][ty])tmpS|=key[tx][ty];
            if(vis[tx][ty][tmpS])continue;
            vis[tx][ty][tmpS]=1;
            if(tx==N&&ty==M)return A.t+1;
            q.push(node(tx,ty,A.t+1,tmpS));
        }
    }
    return -1;
}
int main()
{
    while(scanf("%d%d%d",&N,&M,&P)!=EOF)
    {
        scanf("%d",&K);
        memset(gate,-1,sizeof(gate));
        memset(key,0,sizeof(key));
        for(int i=1;i<=K;i++)
        {
            int a,b,c,d,e;
            scanf("%d%d%d%d%d",&a,&b,&c,&d,&e);
            gate[a][b][c][d]=gate[c][d][a][b]=e;
        }
        scanf("%d",&S);
        for(int i=1;i<=S;i++)
        {
            int x,y,t;
            scanf("%d%d%d",&x,&y,&t);
            key[x][y]|=(1<<(t-1));
        }
        printf("%d\n",BFS(1,1));
    }
    return 0;
}

Smart Software Installer
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 471 Accepted Submission(s): 143

Problem Description
The software installation is becoming more and more complex. An automatic tool is often useful to manage this process. An IT company is developing a system management utility to install a set of software packages automatically with the dependencies. They found that reboot is often required to take effect after installing some software. A software package cannot be installed until all software packages it depends on are installed and take effect.

In the beginning, they implemented a simple installation algorithm, but the system would reboot many times during the installation process. This will have a great impact on the user experience. After some study, they think that this process can be further optimized by means of installing as much packages as possible before each reboot.

Now, could you please design and implement this algorithm for them to minimize the number of restart during the entire installation process?

Input
The first line is an integer n (1 <= n <= 100), which is the number of test cases. The second line is blank. The input of two test cases is separated by a blank line.

Each test case contains m (1 <= n <= 1000) continuous lines and each line is no longer than 1024 characters. Each line starts with a package name and a comma (:). If an asterisk (*) exists between the package name and the comma, the reboot operation is required for this package. The remaining line is the other package names it depends on, separated by whitespace. Empty means that there is no dependency for this software. For example, “a: b” means package b is required to be installed before package a. Package names consist of letters, digits and underscores, excluding other special symbols.

Assume all packages here need to be installed and all referenced packages will be listed in an individual line to define the reboot property. It should be noted that cyclic dependencies are not allowed in this problem.

Output
For each test case, you should output a line starting with “Case #: ” (# is the No. of the test case, starting from 1) and containing the reboot count for this test case. (Refer to the sample format)

Sample Input

2

glibc:
gcc*: glibc

uefi*:
gcc*:
raid_util*: uefi
gpu_driver*: uefi
opencl_sdk: gpu_drivergcc

Sample Output

Case 1: 1
Case 2: 2

题意:告诉你软件之间的依赖关系,带*的是需要重启才生效的,问最小重启几次。
思路:转自:hdu5098
很神奇,相当于先把不需要重启的全部按完,然后把暴露在最外面的需要重启的一块按完,重启一次

#include<iostream>
#include<cstdio>
#include<string>
#include<cstring>
#include<vector>
#include<cmath>
#include<queue>
#include<stack>
#include<map>
#include<sstream>
#include<set>
#include<algorithm>
using namespace std;
const int maxn=10240;
int in[maxn],out[maxn],reboot[maxn];
int tot,cnt;
int head[maxn];
map<string,int> mp;
struct node
{
    int v,next;
}edge[maxn];
void init()
{
    tot=cnt=0;
    mp.clear();
    memset(in,0,sizeof(in));
    memset(out,0,sizeof(out));
    memset(reboot,0,sizeof(reboot));
    memset(head,-1,sizeof(head));
}
char soft[maxn*10];
void add_edge(int x,int y)
{
    edge[tot].v=y;
    edge[tot].next=head[x];
    head[x]=tot++;
}
int topo()
{
    queue<int> q1,q2;
    for(int i=1;i<=cnt;i++)
    {
        if(in[i]==0)
        {
            if(reboot[i])q2.push(i);
            else q1.push(i);
        }
    }
    int ans=0;
    while(!q1.empty()||!q2.empty())
    {
        if(q1.empty()&&!q2.empty())
        {
            ans++;
            while(!q2.empty())
            {
                q1.push(q2.front());
                q2.pop();
            }
        }
        while(!q1.empty())
        {
            int u=q1.front();q1.pop();
            for(int i=head[u];i!=-1;i=edge[i].next)
            {
                int v=edge[i].v;
                in[v]--;
                if(in[v]==0)
                {
                    if(reboot[v])q2.push(v);
                    else q1.push(v);
                }
            }
        }
    }
    return ans;
}
int main()
{
    int T,cas=1;
    scanf("%d",&T);
    getchar();getchar();
    string s;
    while(T--)
    {
        init();
        while(getline(cin,s))
        {
            if(s[0]=='\0')break;
            istringstream ss(s);
            ss>>soft;
            int len=strlen(soft);
            int flag=0;
            if(soft[len-2]=='*')
            {
                flag=1;
                soft[len-2]='\0';
            }
            else soft[len-1]='\0';
            string id(soft),name;
            if(mp.find(id)==mp.end())
            {
                mp[id]=++cnt;
            }
            reboot[mp[id]]=flag;
            while(ss>>name)
            {
                if(mp.find(name)==mp.end())
                {
                    mp[name]=++cnt;
                }
                add_edge(mp[name],mp[id]);
                out[mp[name]]++;
                in[mp[id]]++;
            }
        }
        printf("Case %d: %d\n",cas++,topo());
    }
    return 0;
}
版权声明:本文为博主原创文章,未经博主允许不得转载。 举报

相关文章推荐

武汉大学校赛(个人总结+补题)

【题意】: B.Color Input file: standard input Output file: standard output Time limit: 1 second Me...

2012 ACM/ICPC Asia Regional Changchun Online(hdu 4267 - 4277)线段树+dp+dfs+树形dp

A Simple Problem with IntegersProblem Description Let A1, A2, … , AN be N elements. You need to dea...

HDU 3081 Marriage Match II(二分+并查集+最大流)

题意:有N个女孩要与N个男孩玩配对游戏.每个女孩有一个可选男孩的集合(即该女孩可以选自己集合中的任意一个男孩作为该轮的搭档).然后从第一轮开始,每个女孩都要和一个不同的男孩配对.如果第一轮N个女孩都配...

山东省第六届ACM省赛题——Circle of Friends(强连通分量+dfs)

题目描述 Nowadays, “Circle of Friends” is a very popular social networking platform in WeChat. We can s...

【ZOJ3921 2016年浙大2月月赛G】【爆搜+智商贪心剪枝 好题】Guan Dan 2副牌取27张最少出光牌次数

Guan Dan Time Limit: 2 Seconds      Memory Limit: 65536 KB Bob is playing a poker game called Guan...

【HDU5579 2015上海赛区G】【超级大讨论】Game of Arrays a[]+b[]+c[]有些位置可以减一,状态是否可能达成

Game of Arrays Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) T...

codeforces 453A. Little Pony and Expected Maximum (概率与期望+快速幂)

A. Little Pony and Expected Maximum time limit per test 1 second memory limit per test 2...

【HDU】3341 Lost's revenge AC自动机+变进制+DP

Lost's revenge Time Limit: 15000/5000 MS (Java/Others)    Memory Limit: 65535/65535 K (Java/Others)...

CF - 754B. Ilya and tic-tac-toe game 模拟+暴力

1.题目描述: B. Ilya and tic-tac-toe game time limit per test 2 seconds memory ...

ICCV 2011 on the web

Session 1: Recognition A Graph-matching Kernel for Object Categorization (PDF) Olivier Duchenne,...
收藏助手
不良信息举报
您举报文章:深度学习:神经网络中的前向传播和反向传播算法推导
举报原因:
原因补充:

(最多只允许输入30个字)