UPC第46场部分题解

UPC第46场部分题解

这场简单题比较多,基本看懂题意就能A

A: 小凯的疑惑(数论)

A与B互质时,A与B最大不能表达出的数是多少?

打表找规律。。。结论为:
a n s = a ∗ b − a − b ans=a*b-a-b ans=abab

B: Irreducible Polynomial(数论)

In mathematics, a polynomial is an expression consisting of variables (also called indeterminate) and coefficients, that involves only the operations of addition, subtraction, multiplication, and non-negative integer exponents of variables. For example, x2 + 4x + 7.

A polynomial is said to be irreducible if it cannot be factored into two or more non-trivial polynomials with real coefficients.
For example, x2+1 is irreducible, but x2-2x+1 is not (since x2-2x+1=(x-1)(x-1)).

Given a polynomial of degree with integer coefficients: anxn+an−1xn−1+…+a1x+a0, you need to check whether it is irreducible or not.

给你一个多项式,问你能不能将其因式分解,可以分解成实数。

这其实也是一个结论题,实数域上,不可拆分只有两种:一次多项式和二次多项式(△ < 0)。

c o d e : code: code

#include<stdio.h>
#include<stdlib.h>
#include <bits/stdc++.h>
#define ll long long
using namespace std;
// typedef struct Node *List;
ll a[10101];
int main()
{
    int n,t;
    cin >> t;
    while(t--)
    {
        cin >> n;
        for(int i=1;i<=n+1;i++)
        {
            cin >> a[i];
        }
        if(n>2) printf("No\n");
        else if(n==1) printf("Yes\n");
        else
        {
           ll t=a[2]*a[2]-4*a[1]*a[3];
            if(t<0)
            {
                printf("Yes\n");
            }
            else
            {
                printf("No\n");
            }
        }
    }
	return 0;
}

C: Distant Pastures(最短路)

Farmer John’s farm is made up of an N x N grid of pastures, where each pasture contains one of two different types of grass. To specify these two types of grass, we use the characters ( and ), so for example FJ’s farm might look like the following grid:
(())
)()(
)(((
))))

When Bessie the cow travels around the farm, it takes her A units of time to move from a pasture to an adjacent pasture (one step north, south, east, or west) with the same grass type, or B units of time to move to an adjacent pasture with a different grass type. Whenever Bessie travels from one pasture to a distant pasture, she always uses a sequence of steps that takes the minimum amount of time. Please compute the greatest amount of time Bessie will ever need to take while traveling between some pair of pastures on the farm.

给定一个 n× n的一个网格,每个格子有一个字符,要么是’(‘,要么是’)’。每个格子和它的上下左右的四个格子相邻,对于相邻的两个格子 xy,从 x走到 y的过程中,如果 xy中的字符相同,消耗 A单位时间,如果 xy中字符不同,消耗 B单位时间。定义点 S到点 T的时间为 D( S, T),现在想请你求出网格中最大的 D( S, T)。

老路子了,把a和b作为不同情况点的权值,之后无脑跑spfa就好,枚举起点和终点跑n*n次spfa,每一次记得都要求dis数组的最大值,不断更新就好。

c o d e : code: code:

#include <bits/stdc++.h>
#define ll long long
using namespace std;
const int maxn=5500,mod = 998244353;
inline int read()
{
    int X=0,w=0; char ch=0;
    while(!isdigit(ch)) {w|=ch=='-';ch=getchar();}
    while(isdigit(ch)) X=(X<<3)+(X<<1)+(ch^48),ch=getchar();
    return w?-X:X;
}
inline void write(int x)
{
     if(x<0) putchar('-'),x=-x;
     if(x>9) write(x/10);
     putchar(x%10+'0'+' ');
}

struct node
{
    int x,y;
};
ll ans,dis[102][102];
bool mp[102][102];
int n,a,b;
char s[102][110];
int dx[4]={0,0,-1,1};
int dy[4]={-1,1,0,0};
void spfa(int x,int y)
{
    queue<node>q;
    memset(dis,0x3f3f3f3f3f,sizeof(dis));
    memset(mp,0,sizeof(mp));
    mp[x][y]=1;
    q.push((node){x,y});
    dis[x][y]=0;
    while(!q.empty())
    {
        node d=q.front();
        q.pop();
        mp[d.x][d.y]=0;
        for(int i=0;i<4;i++)
        {
            int sx=d.x+dx[i];
            int sy=d.y+dy[i];
            if(sx>0&&sx<=n&&sy>0&&sy<=n)
            {
                int t1;
                if(s[d.x][d.y]==s[sx][sy])
                {
                    t1=a;
                }
                else
                {
                    t1=b;
                }
                if(dis[sx][sy]>dis[d.x][d.y]+t1)
                {
                    dis[sx][sy]=dis[d.x][d.y]+t1;
                    if(mp[sx][sy]==0)
                    {
                         mp[sx][sy]=1;
                         q.push((node){sx,sy});
                    }
                }
            }
        }
    }
    for(int i=1;i<=n;i++)
    {
        for(int j=1;j<=n;j++)
        {
            ans=max(ans,dis[i][j]);
        }
    }
}
int main()
{

     cin >> n >> a >> b;
     for(int i=1;i<=n;i++)
     {
         for(int j=1;j<=n;j++)
         {
            cin >> s[i][j];
         }
     }
     for(int i=1;i<=n;i++)
     {
         for(int j=1;j<=n;j++)
         {
             spfa(i,j);
         }
     }
     cout << ans;
     return 0;
}

F: Peaks(图论)

There are N observatories in AtCoder Hill, called Obs. 1, Obs. 2, …, Obs. N. The elevation of Obs. i is Hi. There are also M roads, each connecting two different observatories. Road j connects Obs. Aj and Obs. Bj.Obs. i is said to be good when its elevation is higher than those of all observatories that can be reached from Obs. i using just one road. Note that Obs. i is also good when no observatory can be reached from Obs. i using just one road.
How many good observatories are there?

有n个点,m条无向边,给定这n个点的权值和这m条边连结的点.

求有多少个点比它只经过一条边就能到达的所有点各自的权值都更大.

Constraints
·2≤N≤10^5
·1≤M≤10^5
·1≤Hi≤10^9
·1≤Ai,Bi≤N
·Ai≠Bi
·Multiple roads may connect the same pair of observatories.
·All values in input are integers.

图论基础题,链式前向星建图,之后跑循环判断统计次数就好。

c o d e : code: code:

#include<stdio.h>
#include<stdlib.h>
#include <bits/stdc++.h>
#define ll long long
using namespace std;
// typedef struct Node *List;
int n,m,ans,a[202202],head[202202],cnt,x,y;
struct node
{
    int to,next;
}e[401101];
void add(int u,int v)
{
    e[++cnt]=(node){v,head[u]};
    head[u]=cnt;
}
int main()
{
    cin >> n >> m;
    for(int i=1;i<=n;i++)
    {
        scanf("%d",&a[i]);
    }
    for(int i=1;i<=m;i++)
    {
        scanf("%d %d",&x,&y);
        add(x,y);
        add(y,x);
    }
    for(int i=1;i<=n;i++)
    {
        int fl=0;
       for(int j=head[i];j;j=e[j].next)
       {
           if(a[i]<=a[e[j].to])
           {
               fl=1;
               break;
           }
       }
       if(!fl) ans++;
    }
    cout << ans;
	return 0;
}

I: This Message Will Self-Destruct in 5s(map)

You are the top spy of AtCoder Kingdom. To prevent the stolen secret from being handed to AlDebaran Kingdom, you have sneaked into the party where the transaction happens.
There are N attendees in the party, and they are given attendee numbers from 1 through N. The height of Attendee i is Ai.
According to an examination beforehand, you know that a pair of attendees satisfying the condition below will make the transaction.
The absolute difference of their attendee numbers is equal to the sum of their heights.There are N(N−1)/2 ways to choose two from the N attendees and make a pair. Among them, how many satisfy the condition above?

给定一个长度为nn的序列AA,求有多少组ii,jj满足:

  • i<j
  • j − i = a [ i ] + a [ j ] j-i=a[i]+a[j] ji=a[i]+a[j]
  • P.S.: We cannot let you know the secret.

Constraints
·All values in input are integers.
·2≤N≤2×10^5
·1≤Ai≤10^9 (1≤i≤N)

转换一下 j − a [ j ] = i + a [ i ] j-a[j]=i+a[i] ja[j]=i+a[i],扫一遍map统计即可。

c o d e : code: code:

#include<stdio.h>
#include<stdlib.h>
#include <bits/stdc++.h>
#define ll long long
using namespace std;
// typedef struct Node *List;
map<int,int>mp1;
ll a[201015],ans,n;
int main()
{
    cin >> n;
    for(int i=1;i<=n;i++)
    {
        scanf("%d",&a[i]);
    }
    mp1[a[1]+1]++;
    for(int i=2;i<=n;i++)
    {
        ll k=i-a[i],k2=a[i]+i;
        ans+=mp1[k];
        mp1[k2]++;
    }
    cout << ans;
	return 0;
}

L: Typo(栈)

Bessie has just purchased a new laptop computer, but she unfortunately finds herself unable to type well, given the size of her large hooves relative to the small keyboard. Bessie has just attempted to type in one of her favorite patterns – a balanced string of parentheses. However, she realizes that she might have mis-typed one character, accidentally replacing ( with ) or vice versa. Please help Bessie compute the number of locations in the string such that reversing the single parenthesis at that location would cause the entire string to become balanced.

There are several ways to define what it means for a string of parentheses to be “balanced”. Perhaps the simplest definition is that there must be the same total number of ('s and )'s, and for any prefix of the string, there must be at least as many ('s as )'s. For example, the following strings are all balanced:
()
(())
()(()())

while these are not:
)(
())(
((())))

写错了一个括号,问改变一个括号使序列合法方案数。

我们使用栈来做一遍括号匹配,看看最后栈中元素是不是剩两个,出栈判断括号类型,如果是左括号,在它的右边去找左括号,如果是右括号,在它的左边去找右括号。

c o d e : code: code:

#include<iostream>
#include<iomanip>
#include<cstring>
#include<cmath>
#include<cstdio>
#include <vector>
#include <set>
#include<algorithm>
#include <bits/stdc++.h>
#define ll long long
using namespace std;
const int maxn=5500,mod = 998244353;
inline int read()
{
    int X=0,w=0; char ch=0;
    while(!isdigit(ch)) {w|=ch=='-';ch=getchar();}
    while(isdigit(ch)) X=(X<<3)+(X<<1)+(ch^48),ch=getchar();
    return w?-X:X;
}
inline void write(int x)
{
     if(x<0) putchar('-'),x=-x;
     if(x>9) write(x/10);
     putchar(x%10+'0'+' ');
}
char s[100001];
stack<int>st;
ll ans;
int main()
{
     scanf("%s",s+1);
     int n1=strlen(s+1);
     for(int i=1;i<=n1;i++)
     {
         if(st.empty())
         {
             st.push(i);
         }
        else
        {
            if(s[i] == '(')
            {
                st.push(i);
            }
            else if(s[i] == ')')
            {
                if(s[st.top()] == '(')  st.pop();

                else st.push(i);
            }
        }
     }

     if(st.size()==2)
     {
         if(s[st.top()]==')')
         {
             int r=st.top();
             for(int i=0;i<r;i++)
             {
                 if(s[i]==')')
                 {
                     ans++;
                 }
             }
         }
         else
         {
             int r=st.top();
             for(int i=r;i<=n1;i++)
             {
                 if(s[i]=='(')
                 {
                     ans++;
                 }
             }
         }
     }
     cout << ans;
     return 0;
}

M: Tower

有N个块,编号为1,2,…,N。对于每个i(1≤我≤N) ,块i的重量为wi,坚固度为si,值为vi。

塔罗决定建造一座塔楼,从N个木块中挑选一些,并按一定顺序垂直堆放。在此,风塔必须满足以下条件:

对于塔架中包含的每个区块i,其上方堆叠区块的重量总和不大于si。

查找塔中包含的块的最大可能值之和。

这个题要排序后DP,怎么排序?显然我们要就是对于i , j ,将他们反过来一定不会更劣。
a s − b w > b s − a w a_s-b_w>b_s-a_w asbw>bsaw
我们定义DP[I]为剩下多少时的最大值,方程有:

f[min(j-a[i].w,a[i].s)]=max(f[min(j-a[i].w,a[i].s)],f[j]+a[i].v);

c o d e : code: code:

#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
#define LL long long
using namespace std;
LL f[10010];
struct node{int w,s,v;}a[1010];
int n,m;
bool cmp(node a,node b) {return a.s-b.w>b.s-a.w;}
int main()
{
	scanf("%d",&n);
	for(int i=1;i<=n;i++) scanf("%d %d %d",&a[i].w,&a[i].s,&a[i].v);
	sort(a+1,a+n+1,cmp);
	for(int i=1;i<=n;i++)
	{
		for(int j=a[i].w;j<=10000;j++) f[min(j-a[i].w,a[i].s)]=max(f[min(j-a[i].w,a[i].s)],f[j]+a[i].v);
		f[a[i].s]=max(f[a[i].s],(LL)a[i].v);
	}
	LL ans=0;
	for(int i=0;i<=10000;i++) ans=max(ans,f[i]);
	printf("%lld",ans);
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

\ 安 /

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值