2019ACM/CCPC广西省赛

A Scoring Board

Problem Description

In programming contests, the scoring board shows each team’s judge results. Assume there is only one problem in the contest, the scoring board will show according to the rules below:

  • When there is no submissions, the scoring board will show “-”.
  • When there is no “WA” before “AC”, the scoring board will show “+”.
  • When the team failed to solve the problem, the scoring board will show “-k”,where k is the number of “WA”.
  • When the team passed the problem with several tries, the scoring board will show “+k”, where k is the number of “WA” before “AC”.
  • Please write a program to show the scoring board.

Input

The first line of the input contains an integer T(1 ≤ T ≤ 50), denoting the number of test cases.
In each test case, there is one integer n(0 ≤ n ≤ 50) in the first line, denoting the number of submissions.
In the second line, there are n strings s1, s2, . . . , sn(si ∈ {“AC”, “WA”}), denoting the judge results of each submission. The submissions have already been sorted by time.

Output

For each test case, print a single line, denoting what the scoring board shows.

Sample Input

5

4 WA WA WA AC

5 WA WA WA AC WA

1 AC

2 WA WA

0

Sample Output

+3

+3

+

-2

-

 

分析:简单的输入输出题 按照题目要求模拟就可以

#include<bits/stdc++.h>
using namespace std;
int main()
{
	int t;scanf("%d",&t);
	while (t--)
	{
		int n;scanf("%d",&n);
		int flag=0,res=0;
		while (n--)
		{
			string a;
			cin>>a;
			if(a=="WA" && !flag) res++;
			if(a=="AC") flag=1;
		}
		if(flag)
		{
			if(!res) printf("+\n");
			else printf("+%d\n",res);
		}
		else
		{
			if(!res) printf("-\n");
			else printf("-%d\n",res);
		}
	}
	return 0;
}

B Catering

Problem Description

Mr. Bread owns a catering company and business is booming. The company is planning to open some new restaurants. There are n possible locations to open restaurant, the i-th location will hire ai staff, and will need bi staff when things are busy.
The company wants to choose as many as possible locations to open new restaurants. The only constrait is that every new restaurant should have enough staff in busy. Fortunately, there will be at most one restaurant in busy each day, so a plan is valid if ∑ai ≥ max(bi).
Please write a program to determine how many locations can be choosen.

Input

The first line of the input contains an integer T(1 ≤ T ≤ 10000), denoting the number of test cases.
In each test case, there is one integer n(1 ≤ n ≤ 100000) in the first line, denoting the number of possible locations.
For the next n lines, each line contains two integers ai , bi(1 ≤ ai , bi ≤ 1e9), describing each location.
It is guaranteed that ∑n ≤ 1e6.

Output

For each test case, print a single line containing an integer, denoting the maximum number of choosen locations.

Sample Input

2

2

3 4

2 5

2

3 4

2 6

Sample Output

2

0

题意:一个公司有n个部门,给出每个部门的已有雇员数和忙碌时需要的雇员数,问最多能有多少个部门一起工作而不会出现人手不够

分析:题目上说最多每次只有一个部门处于忙碌状态,那么就排个序跑一遍,看有多少部门不行

#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int maxn=1e5+7;
struct node{int a,b;} p[maxn];
bool cmp(node x,node y) 
{
    if(x.b==y.b) return x.a<y.a;
    return x.b>y.b; 
}
int main()
{
    int t;scanf("%d",&t);
    while (t--)
    {
        int n,ans=0;
        ll sum=0;
        scanf("%d",&n);
        for (int i=0;i<n;i++) scanf("%d%d",&p[i].a,&p[i].b),sum+=1ll*p[i].a;
        sort(p,p+n,cmp);
        for (int i=0;i<n;i++)
        {
            if(p[i].b>sum) {sum-=1ll*p[i].a;ans++;}
            else break;
        }
        printf("%d\n",n-ans);
    }
    return 0;
}

C Toy Cars

Problem Description

Hamster is a little boy - he is only three years old and enjoys playing with toy cars very much. Hamster has n different cars, labeled by 1, 2, . . . , n. They are kept on a long straight trail from left to right. The i-th car occupies the interval [li, ri] of the trail. Two adjacent cars can touch, but can’t overlap, so li ≥ ri−1 always holds for all i = 2, 3, . . . , n.
You are a guest visiting Hamster’s house. Hamster invites you to play toy cars together. He will give you m commands. There are three kinds of commands:

  • L x k, move the x-th toy car to the left by k. That is, assume the x-th car is at [lx, rx], move it to [lx − k, rx − k]. Negative coordinates are allowed.
  • R x k, move the x-th toy car to the right by k. That is, assume the x-th car is at [lx, rx], move it to [lx + k, rx + k].
  • ? x, you should tell Hamster lx.
  • Note that the car being moved might “bump into” another car. The moving car can push other cars if touched.
    Please write a program to help Hamster play toy cars.

Input

The first line of the input contains an integer T(1 ≤ T ≤ 10), denoting the number of test cases.
In each test case, there are two integers n, m(1 ≤ n, m ≤ 2000) in the first line, denoting the number of toy cars and commands.
For the next n lines, each line contains two integers li, ri(1 ≤ li ≤ ri ≤ 1e8), describing each toy car. It is guaranteed that li ≥ ri−1 for all i = 2, 3, . . . , n.
For the next m lines, each line describes an event, and it is guaranteed that 1 ≤ x ≤ n and 1 ≤ k ≤ 1e5.

Output

For each query command, print a single line containing an integer, denoting the answer.

Sample Input

1

4 5

1 2

4 6

6 9

9 10

L 2 2

? 2

L 2 2

? 2

? 1

Sample Output

2

0

-1

 

题意:将一个区间左移右移k个单位 询问某一个区间的左端点

分析:这不是模拟一下就好了嘛嘤嘤嘤

#include<bits/stdc++.h>
using namespace std;
const int maxn=2007;
using namespace std;
struct node{int l,r;} p[maxn];
int main()
{
    int t;scanf("%d",&t);
    while (t--)
    {
        int n,m;scanf("%d%d",&n,&m);
        for (int i=1;i<=n;i++) scanf("%d%d",&p[i].l,&p[i].r);
        while (m--)
        {
            char c;cin>>c;
            if (c=='L')
            {
                int x,k;scanf("%d%d",&x,&k);
                p[x].l-=k;p[x].r-=k;
                for (int i=x-1;i>0;i--)
                {
                    int tt=p[i].r-p[i].l;
                    if(p[i].r>p[i+1].l)
                    {
                        p[i].r=p[i+1].l;
                        p[i].l=p[i].r-tt;
                    }
                }
            }
            if (c=='R')
            {
                int x,k;scanf("%d%d",&x,&k);
                p[x].l+=k;p[x].r+=k;
                for (int i=x+1;i<=n;i++)
                {
                    int tt=p[i].r-p[i].l;
                    if(p[i-1].r>p[i].l)
                    {
                        p[i].l=p[i-1].r;
                        p[i].r=p[i].l+tt;
                    }
                }
            }
            if (c=='?')
            {
                int x;scanf("%d",&x);
                printf("%d\n",p[x].l);
            }
        }
    }
    return 0;
}

E Factorization

Problem Description

You are given a positive integer n(n > 1). Consider all the different prime divisors of n. Each of them is included in the expansion n into prime factors in some degree.
Assume n = pe11pe22...pemm , where pi are different prime divisors of n and ei ≥ 1. Your task is to find the greatest common divisor of e1, e2, . . . , em.

Input

The first line of the input contains an integer T(1 ≤ T ≤ 10000), denoting the number of test cases.
In each test case, there is only one integer n(2 ≤ n ≤ 1e18).

Output

For each test case, print a single line containing an integer, denoting the answer.

Sample Input

3

4

6

36

Sample Output

2

1

2

 

题意:T组数据,每组一个数,写出这个数的质因子分解式的最大幂数

看到T是10000,n是1e18我就当场傻掉了,于是写了一发暴力,果不其然t掉了,然后写完后面的题之后回过头来a掉

分析:首先我们知道long long的最大是2^64,那么显然本题的答案不会超过64,于是就想到了从大到小枚举答案,满足则break;具体操作就是给原数开ans次根,再判断ans次方后能否等于原数,如果相等,那么就是答案;要特别注意的是long long还是pow函数的会吃精度,要给开根出来的底数再+1判断一下

#include<bits/stdc++.h>
#define ll long long
using namespace std;
ll qpow(ll base, ll n)
{
    ll res=1;
    while (n>0)
    {
        if (n&1)
            res*=base; 
        base*=base;
        n>>=1;
    }
    return res;
}
int main()
{
    int t;scanf("%d",&t);
    while (t--)
    {
        ll x;scanf("%lld",&x);
        int tmp=70;
        while (1)
        {
            if(tmp==1) break;
            ll res=1ll*(pow(1.0*x,1.0/tmp));
            int flag=1;
            if(qpow(res+1,1ll*tmp)!=x && qpow(res,1ll*tmp)!=x) flag=0;
            if(!flag) tmp--;
            else break;
        }
        printf("%d\n",tmp);
    }
    return 0;
}

D Guess the Number

Problem Description

Professor Elephant has n numbers f1, f2, . . . , fn but he doesn’t want to tell you the numbers directly.
Instead, you should give him some money to buy some useful imformation.
You can buy two types of information:

  • ? x, ask the value of fx, each information will cost you cx dollars.
  • ? a[i] b[i], ask the value of fa[i] − fb[i], each information will cost you w[i] dollars.
  • You can buy information for many times. Please pay as few as possible dollars to make sure that you can know all the n numbers.

Input

The first line of the input contains an integer T(1 ≤ T ≤ 10), denoting the number of test cases.
In each test case, there are two integers n,m(1 ≤ n ≤ 100000, 0 ≤ m ≤ 200000) in the first line, where m denotes the number of information in the form of ? a[i] b[i].
In the second line, there are n integers c1, c2, . . . , cn(1 ≤ ci ≤ 1e9), denoting the cost of type 1.
For the next m lines, each line contains three integers a[i], b[i], w[i](1 ≤ a[i] < b[i] ≤ n, 1 ≤ w[i] ≤ 1e9), describing each information of type 2.

Output

For each test case, print a single line containing an integer, denoting the minimum cost.

Sample Input

1

2 1

5 7

1 2 4

Sample Output

9

 

题意:T组数据,n个第一种信息,m个第二种信息,第一种信息是指查询Fi的花费,第二种信息是指查询Fa-Fb的花费,求能够知道所有Fi的最小花费

分析:第二种信息看作一条边,第一种信息看作0和i的边,最小生成树 Kruscal水题 (没必要像我这样双向边)

#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int maxn=1e6+100;
const int maxm=1e6+100;
int n,m,tot;
ll sum;
struct node
{
    int a,b,val;
}A[maxm];
int pre[maxn];
int find(int x)
{
    if (x==pre[x]) return pre[x];
    else return pre[x]=find(pre[x]);
}
bool cmp(node x,node y)
{
    return x.val<y.val;
}
bool merge(int x,int y)
{
    int fx=find(x),fy=find(y);
    if (fx==fy) return false;
        else pre[fx]=fy;
    return true;
}
int main()
{
    int t;scanf("%d",&t);
    while (t--)
    {
        tot=0;sum=0;
        scanf("%d%d",&n,&m);
        for (int i=0;i<=n;i++) pre[i]=i;
        int cnt=0;
        for (int i=1;i<=n;i++)
        {
            int x;scanf("%d",&x);
            A[++cnt]={0,i,x};
            A[++cnt]={i,0,x};
        }
        for (int i=0;i<m;i++) 
        {
            int x,y,z;scanf("%d%d%d",&x,&y,&z);
            A[++cnt]={x,y,z};
            A[++cnt]={y,x,z};
        }
        sort(A+1,A+cnt+1,cmp);
        for (int i=1;i<=cnt;i++)
        {
            if (merge(A[i].a,A[i].b)) {tot++;sum+=1ll*A[i].val;}
            if (tot==n) break;
        }
        printf("%lld\n",sum);
    }
    return 0;
}

F Permutation

Problem Description

In mathematics, a permutation of n is a set of integers p1, p2, . . . , pn where 1 ≤ pi ≤ n and pi ≠ pj for all pairs of (i, j)(i ≠ j).
It is not hard to figure out that the number of permutations of n is n!. In this task, you are given n integers a1, a2, . . . , an, please figure out how many permutations of n are good.
A permutation is good if and only if pi ≤ ai for all i ∈ [1, n].

Input

The first line of the input contains an integer T(1 ≤ T ≤ 10000), denoting the number of test cases.
In each test case, there is one integer n(1 ≤ n ≤ 100000) in the first line.
In the second line, there are n integers a1, a2, ..., an(1 ≤ ai ≤ n).
It is guaranteed that ∑n ≤ 1e6.

Output

For each test case, print a single line containing an integer, denoting the number of good permutations.
As the answer can be very large, output it modulo 1e9 + 7.

Sample Input

2

3

3 3 3

3

1 3 3

Sample Output

6

2

 

题意:第i位上可以取小于等于a[i]的数,但n个数两两不同,问有多少种数列

分析:从小到大排序,因为小的可以限制大的,当前a[i]减去前面的数字位数就是当前可取,可以用组合数理解一下

#include<bits/stdc++.h>
#define ll long long
#define mod (int(1e9)+7)
using namespace std;
const int maxn=1e5+7;
int a[maxn];
int main()
{
    int t;scanf("%d",&t);
    while (t--)
    {
        int n;scanf("%d",&n);
        for (int i=0;i<n;i++) scanf("%d",&a[i]);
        sort(a,a+n);
        ll ans=1ll*a[0],tmp=1;
        for (int i=1;i<n;i++)
        {
            ll x=1ll*a[i]-tmp;
            ans=(ans*x)%mod;
            tmp++;
        }
        printf("%lld\n",ans%mod);
    }
    return 0;
}

G Math Expression

Problem Description

Given a sequence of integers a1, a2, . . . , an. You should insert exactly one operation between ai and ai+1 for all i ∈ [1, n − 1]. The only operations you can choose to insert are “+” and “×”, so there are 2n−1 ways in total.
Your task is to count how many possible ways of insertion that the value of the final math expression is a multiple of integer k.
For example, assume the sequence is 2, 1, 2 and k = 2, there are 4 possible ways of insertion:

  • 2 + 1 + 2 = 5, is not a multiple of 2.
  • 2 + 1 × 2 = 4, is a multiple of 2.
  • 2 × 1 + 2 = 4, is a multiple of 2.
  • 2 × 1 × 2 = 4, is a multiple of 2.

Input

The first line of the input contains an integer T(1 ≤ T ≤ 10), denoting the number of test cases.
In each test case, there are two integers n,k(2 ≤ n, k ≤ 300) in the first line.
In the second line, there are n integers a1, a2, . . . , an(1 ≤ ai ≤ 1e9), denoting the sequence.

Output

For each test case, print a single line containing an integer, denoting the number of possible ways of insertion. As the answer can be very large, output it modulo 1e9 + 7.

Sample Input

1

3 2

2 1 2

Sample Output

3

 

题意:T组数据,给出n和k,在这n个数间放+或*,使得式子的答案是k的倍数,问有多少种方式

分析:赛场上没有思路,赛后1A,数据只有300,想到dp,男朋友三维的t掉了,我就直接用二维+滚动处理了(不过也有dalao三维卡着时间ac了)。

dp[i][j][l][k]表示到第i位,当前表达式值为j,上一个是+(l==0)还是*(l==1),上一段连续的值是k的方案数

感谢11-大佬教我%%%

#include<bits/stdc++.h>
using namespace std;
const int maxn=307;
const int mod=(int)1e9+7;
int dp[2][maxn][2][maxn],a[maxn];
int main()
{
	int t;scanf("%d",&t);
	while (t--)
	{
		int n,m;scanf("%d%d",&n,&m);
		for (int i=1;i<=n;i++) scanf("%d",&a[i]),a[i]%=m;
		int t=0;
		for (int j=0;j<m;j++)
			for (int k=0;k<m;k++) dp[t][j][0][k]=dp[t][j][1][k]=0;
		dp[t][a[1]][0][a[1]]=1;
		for (int i=2;i<=n;i++)
		{
			t^=1;
			for (int j=0;j<m;j++)
				for (int k=0;k<m;k++) dp[t][j][0][k]=dp[t][j][1][k]=0;
			for (int j=0;j<m;j++)
				for (int k=0;k<m;k++)
				{
					if(dp[t^1][j][0][k])
					{
						//++
						dp[t][(j+a[i])%m][0][a[i]]=(dp[t][(j+a[i])%m][0][a[i]]+dp[t^1][j][0][k])%mod;
						//+*
						dp[t][(j-k+k*a[i]+m)%m][1][(a[i]*k)%m]=(dp[t][(j-k+k*a[i]+m)%m][1][(a[i]*k)%m]+dp[t^1][j][0][k])%mod;
					}
					if(dp[t^1][j][1][k])
					{
						//**
						dp[t][(j-k+k*a[i]+m)%m][1][(a[i]*k)%m]=(dp[t][(j-k+k*a[i]+m)%m][1][(a[i]*k)%m]+dp[t^1][j][1][k])%mod;
						//*+
						dp[t][(j+a[i])%m][0][a[i]]=(dp[t][(j+a[i])%m][0][a[i]]+dp[t^1][j][1][k])%mod;
					}
				}
		}
		int ans=0;
		for (int i=0;i<m;i++)
		{
			ans=(ans+dp[t][0][0][i])%mod;
			ans=(ans+dp[t][0][1][i])%mod;
		}
		printf("%d\n",ans);
	}
	return 0;
}

H Map Tiles

Problem Description

You are a developer of a 2D computer game. Your job is to draw maps in the game. The designer has already designed the map of the game, so what you need to do is to cut the picture into very small square tiles.
Assume the size of the picture is w × h, the picture can be saved as a matrix g[0 . . . w − 1, 0 . . . h − 1].
You need to find the smallest integer k that g[i, j] = g[i mod k, j mod k] always holds for all pairs of (i, j)(0 ≤ i < w, 0 ≤ j < h).

Input

The first line of the input contains an integer T(1 ≤ T ≤ 10), denoting the number of test cases.
In each test case, there are two integers w, h(1 ≤ w,h ≤ 200) in the first line.
For the next w lines, each line contains a string of length h, which only contains lower-case letters, denoting the picture.

Output

For each test case, print a single line containing an integer, denoting the smallest value of k.

Sample Input

3

3 6

ababab

cdcdcd

ababab

2 2

ab

cd

3 3

aaa

aaa

aaa

Sample Output

2

2

1

 

题意:使得所有g[i, j] = g[i mod k, j mod k]的最小k值

分析:暴力判一下,简单题

#include<bits/stdc++.h>
using namespace std;
const int maxn=205;
char mp[maxn][maxn];
int main()
{
    int t;scanf("%d",&t);
    while (t--)
    {
        int n,m;scanf("%d%d",&n,&m);
        for (int i=0;i<n;i++)
            for (int j=0;j<m;j++) cin>>mp[i][j];
        int mx=max(n,m);
        int ans=-1;
        for (int k=1;k<=mx;k++)
        {
            int flag=1;
            for (int i=0;i<n;i++)
            {
                for(int j=0;j<m;j++) if(mp[i][j]!=mp[i%k][j%k]) {flag=0;break;}
                    if(!flag) break;
            }
            if(flag) {ans=k;break;}
        }
        if (ans==-1) ans=mx;
        printf("%d\n",ans);
    }
    return 0;
}

 

  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值