【题目记录】——ICPC银川2019


题目集地址 2019ICCPC银川
参考题解 2019 ICPC亚洲区域赛银川赛区题解

A Girls Band Party 分组背包

题目地址A Girls Band Party
参考文章Girls Band Party(2019银川A题)
题目大意:给出 n ( n ≤ 100000 ) n(n\leq100000) n(n100000)个物品,每个物品有一个name属性和一个color属性和一个power,再给出5个name值和1个color值。选出5个物品,定义bonus初始为1,每有一个物品的name在给出的name中则 b o n u s + = 10 % bonus+=10\% bonus+=10%,每有一个物品的color为给出的color则 b o n u s + = 20 % bonus+=20\% bonus+=20%,定义 得 分 = 5 个 物 品 p o w e r 的 和 × b o n u s 得分=5个物品power的和\times bonus =5power×bonus,求选出的5个物品得分最高为多少,每个名字只能选一次
思路:分组背包,把名字相同的分为一组,然后把五件物品当作第一变化量,每个的奖励百分比当作第二变化量

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <string>
#include <iostream>
#include <map>
#include <vector>

using namespace std;

const int maxn = 1e5 + 7;

map<string,int>mp1,mp2;
int dp[maxn][6][16];

struct Node
{
    int val,num;
    string name,color;
    bool operator < (const Node&rhs)const
    {
        return name < rhs.name;
    }
}a[maxn];

vector<Node>G[maxn];

void init(int n)
{
    memset(dp,-1,sizeof(dp));
    mp1.clear();mp2.clear();
    for(int i = 1;i <= n;i++)G[i].clear();
}

int main()
{
    int T;scanf("%d",&T);
    while(T--)
    {
        int n;scanf("%d",&n);
        init(n);
        for(int i = 1;i <= n;i++)
        {
            cin >> a[i].name >> a[i].color >> a[i].val;
        }

        string tmp;
        for(int i = 1;i <= 5;i++)
        {
            cin >> tmp;mp1[tmp] = 1;
        }
        cin >> tmp;mp2[tmp] = 2;

        sort(a + 1,a + 1 + n);
        int cnt = 0;
        for(int i = 1;i <= n;i++)
        {
            if(a[i].name != a[i - 1].name)
            {
                cnt++;
            }
            a[i].num = mp1[a[i].name] + mp2[a[i].color];
            G[cnt].push_back(a[i]);
        }

        dp[0][0][0] = 0;
        for(int i = 1;i <= cnt;i++)
        {
            for(int k = 0;k <= 5;k++)
            {
                for(int q = 0;q <= 15;q++)
                {
                    dp[i][k][q] = dp[i - 1][k][q];
                }
            }
            for(int j = 0;j < G[i].size();j++)
            {
                int val = G[i][j].val,num = G[i][j].num;

                for(int k = 1;k <= 5;k++)
                {
                    for(int q = num;q <= 15;q++)
                    {
                        if(dp[i - 1][k - 1][q - num] != -1)
                        {
                            dp[i][k][q] = max(dp[i][k][q],dp[i - 1][k - 1][q - num] + val);
                        }
                    }
                }
            }
        }

        int ans = 0;
        for(int i = 0;i <= 5;i++)
        {
            for(int j = 0;j <= 15;j++)
            {
                ans = max(ans,dp[cnt][i][j] * (10 + j) / 10);
            }
        }
        printf("%d\n",ans);
    }
    return 0;
}

B So Easy 思维

题目地址B So Easy
题目大意:一个 n × m n\times m n×m 矩阵, n m ≥ 2 n m\geq 2 nm2,初始全0,每次可以行+1或列+1。现在某一个数丢失,求它是多少。
思路:有这样一个规律 a x y + a z w = a x w + a z y a_{xy}+a_{zw}=a_{xw}+a_{zy} axy+azw=axw+azy

#include <bits/stdc++.h>
#define ll long long
#define INF 0x3f3f3f3f
using namespace std;
const int N=1e3+3;
int maze[N][N];
void solve()
{
    int n,px,py;
    cin >> n;
    for(int i = 1;i <= n;i++)
    {
        for(int j = 1;j <= n;j++)
        {
            cin >> maze[i][j];
            if(maze[i][j]==-1)
            {
                px=i;
                py=j;
            }
        }
    }
    if(px==1&&py==1)
    {
        cout << maze[2][1]+maze[1][2]-maze[2][2] << endl;
    }
    else
    {
        cout << maze[1][py]+maze[px][1]-maze[1][1] << endl;
    }
}

int main()
{
//	freopen("in.txt","r",stdin);
	int t = 1;
//	int t;
//	scanf("%d",&t);
	while(t--)
	{
		solve();
	}
    return 0;
}

D

E

G Pot!! 线段树

题目地址G Pot!!
题目大意:维护一个数组,区间乘一个 2 ≤ x ≤ 10 2\leq x\leq 102≤x≤10 的数字,区间查询 pot ⁡ ( x ) \operatorname{pot}(x)pot(x) 的最大值,其中
pot ⁡ ( x ) : = max ⁡ p   p r i m e ,   p c ∣ x c . \operatorname{pot}(x):=\max_{p\ \mathrm{prime},\ p^c|x}c. pot(x):=p prime, pcxmaxc.
做法:对2,3,5,7分别维护一颗线段树,区间加、区间取max即可。

#include <bits/stdc++.h>
using namespace std;
const int maxn=1e5+10;
struct node {
    int val[8],lazy[8];
} seg[maxn<<2];
int n,q,l,r,x,prime[]= {2,3,5,7};
void PushDown(int rt) {
    for(int i=0; i<4; i++) {
        int t=prime[i];
        if(seg[rt].lazy[t]) {
            seg[rt<<1].val[t]+=seg[rt].lazy[t];
            seg[rt<<1|1].val[t]+=seg[rt].lazy[t];
            seg[rt<<1].lazy[t]+=seg[rt].lazy[t];
            seg[rt<<1|1].lazy[t]+=seg[rt].lazy[t];
            seg[rt].lazy[t]=0;
        }
    }
}
void PushUp(int rt) {
    for(int i=0; i<4; i++) {
        int t=prime[i];
        seg[rt].val[t]=max(seg[rt<<1].val[t],seg[rt<<1|1].val[t]);
    }
}
void Update(int L,int R,int c,int t,int l,int r,int rt) {
    if(L<=l&&R>=r) {
        seg[rt].val[c]+=t;
        seg[rt].lazy[c]+=t;
        return ;
    }
    int mid=(l+r)>>1;
    PushDown(rt);
    if(L<=mid)
        Update(L,R,c,t,l,mid,rt<<1);
    if(R>mid)
        Update(L,R,c,t,mid+1,r,rt<<1|1);
    PushUp(rt);
}
int Query(int L,int R,int l,int r,int rt) {
    if(L<=l&&R>=r) {
        int res=0;
        for(int i=0; i<4; i++) {
            int t=prime[i];
            res=max(res,seg[rt].val[t]);
        }
        return res;
    }
    if(L>r||R<l)return 0;
    int mid=(l+r)>>1;
    PushDown(rt);
    return max(Query(L,R,l,mid,rt<<1),Query(L,R,mid+1,r,rt<<1|1));
}
int main() {
    ios::sync_with_stdio(0);
    cin.tie(0);
    cin >>n>>q;
    while(q--) {
        string s;
        cin >>s;
        switch(s[1]) {
        case 'U':
            cin >>l>>r>>x;
            for(int i=0; i<4; i++)
                if(x%prime[i]==0) {
                    if(x==8) {
                        Update(l,r,prime[i],3,1,maxn,1);
                        break;
                    } else if(x==9||x==4) {
                        Update(l,r,prime[i],2,1,maxn,1);
                        break;
                    }
                    else
                        Update(l,r,prime[i],1,1,maxn,1);
                }
            break;
        case 'A':
            cin >>l>>r;
            cout <<"ANSWER "<<Query(l,r,1,maxn,1)<<endl;
            break;
        }
    }
    return 0;
}

I Base62 进制转换 数学 大数

题目地址I Base62
题目大意:xyz,三个字符串,给出x进制的z转换成y进制输出。A表示10,a表示36
思路:就是普通的进制转换只不过需要用到大数,先将x进制转为10进制,再将数字转为y进制。
我们不太会用c++的大数,就用了java。

import java.math.BigInteger;
import java.util.Scanner;

public class Main {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		String z;
		int x,y;
		Scanner input=new Scanner(System.in);
		x=input.nextInt();
		y=input.nextInt();
		z = input.next();
		if(z.equals("0"))
		{
			System.out.println(0);
			return;
		}
		BigInteger big1=Toten(z, x);
		String res=reverse(ToY(big1, y));
		System.out.println(res);
	}
	
	static String reverse(String str)
	{
		String s="";
		int len = str.length();
		for(int i = len-1;i >= 0;i--)
		{
			s+=str.charAt(i);
		}
		return s;
	}
	static String ToY(BigInteger a,int y) {
		String res="";
		BigInteger zero=new BigInteger("0");
		BigInteger ynum=new BigInteger(""+y);
		int tnum;
		while(!a.equals(zero))
		{
			tnum=Integer.valueOf(a.remainder(ynum).toString());
			res+=inttochar(tnum);
			a=a.divide(ynum);
		}
		return res;
	}
	static BigInteger Toten(String str,int x) {
		BigInteger res=new BigInteger("0");
		BigInteger tb;
		BigInteger tBigInteger=BigInteger.ONE;
		BigInteger k = BigInteger.valueOf(x);
		int len = str.length();
		for(int i = len-1; i >= 0;i--){
			tb=new BigInteger(tBigInteger.toString());
			res=res.add(chartoint(str.charAt(i)).multiply(tb));
			tBigInteger = tBigInteger.multiply(k);
		}
		return res;
	}
	static BigInteger chartoint(Character ch)
	{
		int t=0;
		BigInteger bigInteger;
	    if(ch>='0'&&ch<='9') {
	    	t = ch-'0';
	    }
	    else if(ch>='A'&&ch<='Z') {
	    	t = ch-'A'+10;
	    }
	    else if(ch>='a'&&ch<='z') {
	    	t = ch-'a'+36;
	    }
	    bigInteger=new BigInteger(""+t);
	    return bigInteger;
	}
	static Character inttochar(int n)
	{
	    if(n>=0&&n<=9)
	        return (char) ('0'+n);
	    else if(n>=10&&n<=35)
	        return (char) ('A'+n-10);
	    else
	        return (char) ('a'+n-36);
	}
}

K

N Fibonacci Sequence 简单题

题目地址N Fibonacci Sequence
题目大意:输出斐波那契数列的前5项
思路:输出1 1 2 3 5即可

#include <iostream>
using namespace std;
int main(){
cout << "1 1 2 3 5" << endl;
return 0;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
UIUC ICPC Spring Coding Contest 2019是UIUC(伊利诺伊大学厄巴纳-香槟分校)举办的一个编程比赛。UIUC ICPC Spring Coding Contest 2019是ACM国际大学生程序设计竞赛(ACM International Collegiate Programming Contest)的一部分。ACM国际大学生程序设计竞赛是世界上最具影响力的大学生计算机竞赛之一,每年吸引了来自全球各地的大学生参与。这个比赛旨在培养学生的算法和编程技能,提供一个展示和交流的平台。参赛者需要在规定时间内解决一系列编程问题。 参加UIUC ICPC Spring Coding Contest 2019对于那些对算法和编程有兴趣的学生来说,是一个很好的学习和锻炼机会。比赛中的问题通常涉及各种算法数据结构,要求参赛者能够用编程语言实现有效和高效的解决方案。参赛者可以通过解决问题来提高他们的算法和编程技能,并与其他参赛者交流和学习。 在准备UIUC ICPC Spring Coding Contest 2019之前,建议参赛者先掌握一些基本的编程知识和技能,如数据结构算法、编程语言等。参赛者可以参考一些相关的教程和学习资料,如GeeksforGeeks和HackerEarth等网站提供的编程教程。此外,还可以参考一些竞赛经验分享的文章和博客,了解其他人是如何准备和参加编程比赛的。 总之,参加UIUC ICPC Spring Coding Contest 2019是一个很好的机会,可以提高算法和编程技能,与其他参赛者交流和学习。准备比赛前,建议参赛者掌握基本的编程知识和技能,并参考一些相关的教程和学习资料。祝你在比赛中取得好成绩!<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* *3* [Awesome Competitive Programming Awesome](https://blog.csdn.net/qq_27009517/article/details/86593200)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 100%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值