Playing with Numbers(Kattis - playingwithnumbers)(预处理瞎搞)

2024-01-14 02:32

本文主要是介绍Playing with Numbers(Kattis - playingwithnumbers)(预处理瞎搞),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

题目链接:https://vjudge.net/problem/Kattis-playingwithnumbers

题目描述:给定n组a b的值,每组表示一个数值2^a*3^b,共进行n次操作,第i次操作可以进行i-1次gcd操作和 n - i次lcm操作,求每次操作后所得最大值及最小值对应的ab分别是多少。每次选取任意两个数进行gcd操作时,只将结果放回这些数字中,lcm也是。

思路:当至少进行2次gcd操作时,一定能将两个最小的ab值mina minb组合到一起,所得最小值一定是2^mina*3minb;至少进行2次lcm操作时,一定能将两个最大的ab值mina minb组合到一起,所得最大值一定是2^maxa*3maxb。当只进行gcd或lcm时,所得结果是唯一的,输出即可。当只进行1次gcd时,也就是要选取一个数与其他n-1个数的lcm进行gcd操作,可以预处理好数组lcm1[i]代表除第i个数的a值以外,其他n-1个数的a值进行lcm结果,遍历一遍取最小值,b值求法相同;当只进行1次lcm时,也就是要选取一个数与其他n-1个数的gcd进行lcm操作得到最大值,可以预处理好数组lcm1[i]代表除第i个数以外的a值,其他n-1个数的a值进行lcm结果,遍历一遍取最大值,b值求法相同。代码写的有点麻烦,但是思路还是很简单的,只要别写晕了就行。吐槽一下只有25组测试数据真的很水,场上我的思路不对队友都可以举出反例来竟然照样能AC,没办法最后五分钟算是交着玩了我也不知道会AC啊,队友对此表示难以接受哈哈。写这道题做的最多的就是复制粘贴,醉了。

代码如下:

#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
#include <cmath>
using namespace std;
const int maxn=50000+10;
int n;
int a[maxn],b[maxn];
const int inf=0x3f3f3f3f;
struct node{int a, b;int id;node(int a = 0, int b = 0, int id = 0) : a(a), b(b), id(id) {}
}num[maxn];
int gcd1[maxn], lcm1[maxn], gcd2[maxn], lcm2[maxn];
int max1[maxn], max2[maxn], min1[maxn], min2[maxn];
int mmax1[maxn], mmax2[maxn], mmin1[maxn], mmin2[maxn];
int main(){while(~scanf("%d",&n)){int maxa=0,maxb=0,mina=inf,minb=inf;int dyb,dya,ddyb,ddya;for(int i=1; i<=n; i++){scanf("%d%d",&num[i].a,&num[i].b);if(num[i].a > maxa) maxa = num[i].a;//分别找出最大最小的ab值if(num[i].b > maxb) maxb = num[i].b;if(num[i].a < mina) mina = num[i].a;if(num[i].b < minb) minb = num[i].b;}if(n==1){printf("%d %d %d %d\n",num[1].a,num[1].b,num[1].a,num[1].b); continue;}if(n==2){printf("%d %d %d %d\n",maxa,maxb,maxa,maxb);printf("%d %d %d %d\n",mina,minb,mina,minb);continue;}min1[2] = num[1].a; min2[2] = num[1].b;max1[2] = num[1].a; max2[2] = num[1].b;for(int i = 3; i <= n; ++i){min1[i] = min(num[i - 1].a, min1[i - 1]);//min1[i]表示前i-1个数a中的最小值,也就是i前面所有a的gcd结果min2[i] = min(num[i - 1].b, min2[i - 1]);//i前面所有b的gcd结果max1[i] = max(num[i - 1].a, max1[i - 1]);//i前面所有a的lcm结果max2[i] = max(num[i - 1].b, max2[i - 1]);//i前面所有b的lcm结果}mmin1[n - 1] = num[n].a; mmin2[n - 1] = num[n].b;mmax1[n - 1] = num[n].a; mmax2[n - 1] = num[n].b;for(int i = n - 2; i >= 1; --i){mmin1[i] = min(num[i + 1].a, mmin1[i + 1]);//i后面所有a的gcd结果mmin2[i] = min(num[i + 1].b, mmin2[i + 1]);//i后面所有b的gcd结果mmax1[i] = max(num[i + 1].a, mmax1[i + 1]);//i后面所有a的lcm结果mmax2[i] = max(num[i + 1].b, mmax2[i + 1]);//i后面所有b的lcm结果}gcd1[1] = mmin1[1]; lcm1[1] =  mmax1[1];gcd2[1] = mmin2[1]; lcm2[1] =  mmax2[1];gcd1[n] = min1[n]; lcm1[n] = max1[n];gcd2[n] = min2[n]; lcm2[n] = max2[n];for(int i = 2; i < n; ++i){gcd1[i] = min(min1[i], mmin1[i]);//除第i个数以外其他n-1个a的gcd结果gcd2[i] = min(min2[i], mmin2[i]);//除第i个数以外其他n-1个b的gcd结果lcm1[i] = max(max1[i], mmax1[i]);//除第i个数以外其他n-1个a的lcm结果lcm2[i] = max(max2[i], mmax2[i]);//除第i个数以外其他n-1个a的lcm结果}int cnt = 0;int u,v;int tmp1, tmp2, tmp3, tmp4, x, y;for(int i = 1; i <= n; ++i){tmp1 = tmp2 = 0;tmp3 = tmp4 = 1e9;u = i - 1;//gcdv = n - i;//lcmif(!u){//gcd次数为0,lcm次数为n-1,即求这n个数的最小公倍数,所得结果是唯一的2^maxa*3^maxbprintf("%d %d %d %d\n", maxa, maxb, maxa, maxb); continue;}if(!v){//gcd次数为n-1,lcm次数为0,即求这n个数的最大公约数,所得结果也是唯一的2^mina*3^minbprintf("%d %d %d %d\n", mina, minb, mina, minb); continue;}if(v == 1){//只进行一次lcm时,枚举所有结果取最大值tmp1 = max(num[1].a, gcd1[1]); tmp2 = max(num[1].b, gcd2[1]);for(int i = 2; i <= n; ++i){x = max(gcd1[i], num[i].a); y = max(gcd2[i], num[i].b);//第i个数与其他n-1的数的gcd结果进行lcm操作,也就是取较大者if(x * log(2) + y * log(3) > tmp1 * log(2) + tmp2 * log(3)){tmp1 = x; tmp2 = y;}}}if(u == 1){//只进行一次gcd时,枚举所有结果取最小值tmp3 = min(num[1].a, lcm1[1]); tmp4 = min(num[1].b, lcm2[1]);for(int i = 2; i <= n; ++i){x = min(lcm1[i], num[i].a); y = min(lcm2[i], num[i].b);//第i个数与其他n-1的数的lcm结果进行gcd操作,也就是取较小者if(x * log(2) + y * log(3) < tmp3 * log(2) + tmp4 * log(3)){tmp3 = x; tmp4 = y;}}}if(v >= 2){//进行两次以上lcm,所得最大值一定是2^maxa*3^maxbtmp1 = maxa; tmp2 = maxb;}if(u >= 2){//进行两次以上gcd,所得最小值一定是2^mina*3^minbtmp3 = mina; tmp4 = minb;}printf("%d %d %d %d\n", tmp1, tmp2, tmp3, tmp4);}}return 0;
}/*4
0 0
1 2
2 1
2 23
1 5
4 2
1 15
1 7
2 6
4 5
2 1
9 0*/


这篇关于Playing with Numbers(Kattis - playingwithnumbers)(预处理瞎搞)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/603649

相关文章

计蒜客 Half-consecutive Numbers 暴力打表找规律

The numbers 11, 33, 66, 1010, 1515, 2121, 2828, 3636, 4545 and t_i=\frac{1}{2}i(i+1)t​i​​=​2​​1​​i(i+1), are called half-consecutive. For given NN, find the smallest rr which is no smaller than NN

动手学深度学习【数据操作+数据预处理】

import osos.makedirs(os.path.join('.', 'data'), exist_ok=True)data_file = os.path.join('.', 'data', 'house_tiny.csv')with open(data_file, 'w') as f:f.write('NumRooms,Alley,Price\n') # 列名f.write('NA

高精度打表-Factoring Large Numbers

求斐波那契数,不打表的话会超时,打表的话普通的高精度开不出来那么大的数组,不如一个int存8位,特殊处理一下,具体看代码 #include<stdio.h>#include<string.h>#define MAX_SIZE 5005#define LEN 150#define to 100000000/*一个int存8位*/int num[MAX_SIZE][LEN];void

【动手学深度学习】04 数据操作 + 数据预处理(个人向笔记)

数据操作 N维数组是机器学习和神经网络的主要数据结构其中 2-d 矩阵中每一行表示每一行表示一个样本 当维度来到三维的时候则可以表示成一张图片,再加一维就可以变成多张图片,再加一维则可以变成一个视频 访问元素 冒号表示从冒号左边的元素到冒号右边的前一个元素(开区间),其中如果左边为空,那么表示从第一个开始,如果右边为空,那么表示访问到最后一个,如果两边都为空,则表示全部访问其中一行中我们指

数据预处理与协同过滤推荐算法——从数据清洗到个性化电影推荐

推荐系统在现代应用中占据了重要地位,尤其在电影、音乐等个性化内容推荐中广泛使用。本文将介绍如何使用数据预处理、特征工程以及多种推荐算法(包括协同过滤、基于内容的推荐、混合推荐等)来实现电影推荐系统。通过Pandas、Scikit-learn、TensorFlow等工具,我们将展示如何从数据清洗开始,逐步实现各类推荐算法。  完整项目代码: 基于协同过滤的电影推荐系统 一、数据预处

leetcode#628. Maximum Product of Three Numbers

题目 Given an integer array, find three numbers whose product is maximum and output the maximum product. Example 1: Input: [1,2,3]Output: 6 Example 2: Input: [1,2,3,4]Output: 24 Note: The lengt

leetCode#448. Find All Numbers Disappeared in an Array

Description Given an array of integers where 1 ≤ a[i] ≤ n (n = size of array), some elements appear twice and others appear once. Find all the elements of [1, n] inclusive that do not appear in this

CF Bayan 2015 Contest Warm Up A.(模拟+预处理)

A. Bayan Bus time limit per test 2 seconds memory limit per test 256 megabytes input standard input output standard output 题目链接: http://codeforces.com/contest/475/problem/A The fi

HLJUOJ1003(预处理)

1003: Time Time Limit: 1 Sec   Memory Limit: 128 MB Submit: 27   Solved: 13 [ Submit][ Status][ Web Board] Description Digital clock use 4 digits to express time, each digit is described by

C语言之预处理详情

目录 前言1.预定义符号2.#define定义常量3.#define定义宏4.带有副作用的宏参数5.宏替换的规则6.宏和函数的对比7.#和##运算符7.1 #运算符7.2 ##运算符 8.命名约定9.undef10.命令行指令11.条件编译12.头文件的包含12.1 头文件包含方式12.1.1 本地头文件包含12.1.2 库文件包含 12.2 嵌套文件包含 13.其他预处理指令总结