ACM-ICPC国际大学生程序设计竞赛北京赛区(2017)网络赛

题目1 : Visiting Peking University

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

描述

Ming is going to travel for n days and the date of these days can be represented by n integers: 0, 1, 2, …, n-1. He plans to spend m consecutive days(2 ≤ m ≤ n)in Beijing. During these m days, he intends to use the first day and another day to visit Peking university. Before he made his plan, Ming investigated on the number of tourists who would be waiting in line to enter Peking university during his n-day trip, and the results could be represented by an integer sequence p[i] (0 ≤ i ≤ n-1, p[i] represents the number of waiting tourists on day i). To save time, he hopes to choose two certain dates a and b to visit PKU(0 ≤ a < b ≤ n-1), which makes p[a] + p[b] as small as possible.

Unfortunately, Ming comes to know that traffic control will be taking place in Beijing on some days during his n-day trip, and he won’t be able to visit any place in Beijing, including PKU, on a traffic control day. Ming loves Beijing and he wants to make sure that m days can be used to visit interesting places in Beijing. So Ming made a decision:  spending k (m ≤ k ≤ n) consecutive days in Beijing is also acceptable if there are k - m traffic control days among those k days. Under this complicated situation, he doesn’t know how to make the best schedule. Please write a program to help Ming determine the best dates of the two days to visit Peking University.  Data guarantees a unique solution.

输入

There are no more than 20 test cases.

For each test case:

The first line contains two integers, above mentioned n and m (2 ≤ n ≤ 100, 2 ≤ m ≤ n).

The second line contains n integers, above mentioned p[0] , p[1] , … p[n-1]. (0 ≤ p[i] ≤ 1000, i = 0 ... n-1)

The third line is an integer q (0 ≤ q ≤ n), representing the total number of traffic control days during the n-day trip, followed by q integers representing the dates of these days.

输出

One line, including two integers a and b, representing the best dates for visiting PKU.

样例输入
7 3
6 9 10 1 0 8 35
3 5 6 2
4 2
10 11 1 2
1 2
样例输出
0 3
1 3

这个题意感觉有些模糊啊,就是给你n天,每天都有个权值,但是有几天是不能玩的,让你算算选两天,必须选一天和m天中的另一天,和最小

记录下合法的,直接暴力吧

#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
int main()
{
    int a[101],i,j,n,m,x,y,s,h,u,v,k;
    while(~scanf("%d%d",&n,&m))
    {
        for(i=0;i<n;i++)
        scanf("%d",&a[i]);
        scanf("%d",&x);
        for(i=0;i<x;i++)
        {
            scanf("%d",&y);
            a[y]=-1;
        }
        s=10000;u=v=0;x=y=0;
        for(i=0;i<n;i++)
        {
            if(a[i]==-1)
            continue;
            k=m;
            h=a[i];
            for(j=i+1;j<k+i&&j<n;j++)
            {
                if(a[j]==-1)
                {
                    k++;
                    continue;
                }
                if(h+a[j]<s)
                {
                    s=h+a[j];
                    u=i,v=j;
                }
            }
            if(k+i>n)
            break;
            else x=u,y=v;
        }
        printf("%d %d\n",x,y);
    }
} 

题目9 : Minimum

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

描述

You are given a list of integers a0, a1, …, a2^k-1.

You need to support two types of queries:

1. Output Minx,y∈[l,r] {ax∙ay}.

2. Let ax=y.

输入

The first line is an integer T, indicating the number of test cases. (1≤T≤10).

For each test case:

The first line contains an integer k (0 ≤ k ≤ 17).

The following line contains 2k integers, a0, a1, …, a2^k-1 (-2k ≤ ai < 2k).

The next line contains a integer  (1 ≤ Q < 2k), indicating the number of queries. Then next Q lines, each line is one of:

1. 1 l r: Output Minx,y∈[l,r]{ax∙ay}. (0 ≤ l ≤ r < 2k)

2. 2 x y: Let ax=y. (0 ≤ x < 2k, -2k ≤ y < 2k)

输出

For each query 1, output a line contains an integer, indicating the answer.

样例输入
1
3
1 1 2 2 1 1 2 2
5
1 0 7
1 1 2
2 1 2
2 2 2
1 1 2
样例输出
1
1
4

裸的线段树,需要维护区间最大值最小值,但是最小值最大值的正负未知,需要分情况讨论

#include <bits/stdc++.h>
using namespace std;
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
const int maxn=2e5+5;
int amax[maxn<<2];
int amin[maxn<<2];
int b[maxn];
const int inf=1<<30;
void pushup_max(int rt)
{
    amax[rt]=max(amax[rt<<1],amax[rt<<1|1]);
}
void pushup_min(int rt)
{
    amin[rt]=min(amin[rt<<1],amin[rt<<1|1]);
}
void build_max(int l,int r,int rt)
{
    if(l==r)
    {
        amax[rt]=b[l];
        return ;
    }
    int m=(l+r)>>1;
    build_max(lson);
    build_max(rson);
    pushup_max(rt);
}
void build_min(int l,int r,int rt)
{
    if(l==r)
    {
        amin[rt]=b[l];
        return ;
    }
    int m=(l+r)>>1;
    build_min(lson);
    build_min(rson);
    pushup_min(rt);
}
void update_max(int pos,int bue,int l,int r,int rt)
{
    if(l==r)
    {
        amax[rt]=bue;
        return;
    }
    int m=(l+r)>>1;
    if(pos<=m) update_max(pos,bue,lson);
    else update_max(pos,bue,rson);
    pushup_max(rt);
}
void update_min(int pos,int bue,int l,int r,int rt)
{
    if(l==r)
    {
        amin[rt]=bue;
        return ;
    }
    int m=(l+r)>>1;
    if(pos<=m) update_min(pos,bue,lson);
    else update_min(pos,bue,rson);
    pushup_min(rt);
}
int query_max(int left,int right,int l,int r,int rt)
{
    if(left<=l&&right>=r)
    {
        return amax[rt];
    }
    int m=(l+r)>>1;
    int t=-inf;
    if(left<=m) t=max(t,query_max(left,right,lson));
    if(right>m) t=max(t,query_max(left,right,rson));
    return t;
}
int query_min(int left,int right,int l,int r,int rt)
{
    if(left<=l&&right>=r)
    {
        return amin[rt];
    }
    int m=(l+r)>>1;
    int t=inf;
    if(left<=m) t=min(t,query_min(left,right,lson));
    if(right>m) t=min(t,query_min(left,right,rson));
    return t;
}
int main()
{
    int T;
    scanf("%d",&T);
    while(T--)
    {
        int n;
        scanf("%d",&n);
        n=1<<n;
        for(int i=1; i<=n; i++)
            scanf("%d",b+i);
        build_max(1,n,1);
        build_min(1,n,1);
        int m;
        scanf("%d",&m);
        for(int i=0; i<m; i++)
        {
            int x,l,r;
            scanf("%d%d%d",&x,&l,&r);
            if(x==1)
            {
                int mi=query_min(++l,++r,1,n,1);
                int ma=query_max(l,r,1,n,1);
                if(ma*1LL*mi<=0)printf("%lld\n",ma*1LL*1LL*mi);
                else
                printf("%lld\n",min(ma*1LL*ma,mi*1LL*mi));
            }
            else
            {
                update_max(++l,r,1,n,1);
                update_min(l,r,1,n,1);
            }
        }
    }
    return 0;
}

 

题目7 : Bounce

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

描述

For Argo, it is very interesting watching a circle bouncing in a rectangle.

As shown in the figure below, the rectangle is divided into N×M grids, and the circle fits exactly one grid.

The bouncing rule is simple:

1. The circle always starts from the left upper corner and moves towards lower right.

2. If the circle touches any edge of the rectangle, it will bounce.

3. If the circle reaches any corner of the rectangle after starting, it will stop there.

Argo wants to know how many grids the circle will go through only once until it first reaches another corner. Can you help him?

输入

The input consists of multiple test cases. (Up to 105)

For each test case:

One line contains two integers N and M, indicating the number of rows and columns of the rectangle. (2 ≤ N, M ≤ 109)

输出

For each test case, output one line containing one integer, the number of grids that the circle will go through exactly once until it stops (the starting grid and the ending grid also count).

样例输入
2 2
2 3
3 4
3 5
4 5
4 6
4 7
5 6
5 7
9 15
样例输出
2
3
5
5
7
8
7
9
11
39

找规律,死在这上面了,很难找啊。绝望

题解源于qls,我这种死活动手推规律的傻逼了

献上pp的代码,啧啧称奇

#include <bits/stdc++.h>

using namespace std;

typedef long long ll;

int main(int argc, char *argv[]) {
  cin.sync_with_stdio(false);
  ll n, m;
  while (cin >> n >> m) {
    if (n < m) swap(n, m);
    ll gcd = __gcd(n - 1, m - 1);
    ll k = (m - 1) / gcd;
    ll x = (n - 1) / gcd;
    ll ans = (k - 1) * (m - k + 1) + (x - k + 1) * (m - k);
    cout << ans + 1 << endl;
  }
  return 0;
}

 

posted @ 2017-09-24 07:46  暴力都不会的蒟蒻  阅读(381)  评论(0编辑  收藏  举报