首页 > 其他分享 >2023.10.28 做题记录

2023.10.28 做题记录

时间:2024-06-22 12:53:28浏览次数:11  
标签:le 记录 int rint 相加 2023.10 28 cin define

2023.10.28

[NOIP2018 提高组] 铺设道路

题目传送门

选择一个区间进行“填坑”操作;

所以我们的贪心策略是:

a[i] > a[i - 1] , sum += a[i] - a[i - 1];

假设现在有一个坑,但旁边又有一个坑。

你肯定会选择把两个同时减 1

那么小的坑肯定会被大的坑带着填掉。

所以只要计算每个坑之间的差就可以。

P1106 删数问题

题目传送门

从头遍历,删去下坡数即可。

注意如果全局下坡路的时候倒着删。

[NOIP2012 提高组] 国王游戏

题目传送门

根据题意我们可以知道,大臣 1 和大臣 2 位置能交换的必要条件是:大臣 2 放在大臣 1 的前面得到的最大值更加小。那么我们分别讨论两种情况下的最大值。

假设只有两个大臣

如果大臣 1 放在前面,金币数分别为:\(a_0/b_1\), \(a_0×a_1/b_2\)

如果大臣 2 放在前面,金币数分别为:\(a_0/b_2\), \(a_0×a_2/b_1\)

约去式子里面的 \(a_0\),讨论两种情况的最大值,就变成了比较:\(max(1/b_1, a_1/b_2)\) 和 \(max(1/b_2, a_2/b_1)\)

根据 \(a≥1\),得出: \(a_1/b_2 >= 1/b_2\), \(1/b_1 <= a_2/b_1\)

如果 \(1/b_1\) 是最大的,则 \(1/b_1>=a_2/b_1\),只可能左右两边相等,则 \(1/b_2<=a_2/b_1\),所以两种情况的最大值是一样的,则不用交换。

同理可得 \(1/b_2\) 是最大的情况也不用交换。

那么只要 \(a_1/b_2\) 和 \(a_2/b_1\) 的大小就可以了,如果 \(a_1/b_2>a_2/b_1\),那么就要交换,变形得:\(a_1*b_1 > a_2*b_2\)

无高精度代码如下:

bool cmp(node a, node b)
{
	return a.l * a.r < b.l * b.r;
}

signed main()
{
	cin >> n >> l >> r;
	for (rint i = 1; i <= n; i++)
	{
		cin >> a[i].l >> a[i].r; 
	}
	sort(a + 1, a + n + 1, cmp);
	for (rint i = 1; i <= n; i++)
	{
		ans = max(ans, l / a[i].r);
		l *= a[i].l;
	}
	cout << ans << endl;
}

[SHOI2006] 作业

题目传送门

第一眼没有思路时,我们可以考虑暴力:

\(30pts\) \(Code\) 如下:

#include <bits/stdc++.h>

#define rint register int
#define endl '\n'

using namespace std;

set<int> s;
unordered_map<int, bool> v;

const int N = 3e5 + 5;
int p[N];
int n;

signed main()
{
	int n;
	cin >> n;
	while (n--)
	{
		char op;
		cin >> op;
		if (op == 'A')
		{
			int x;
			cin >> x;
			s.insert(x);
		}
		else
		{
			int x, minn = 1e9;
			cin >> x;
			memset(p, 0, sizeof p);
			int j = 1;
			for (auto i = s.begin(); i != s.end(); i++, j++)
			{
				p[j] = *i;
				//cout << j << " " << p[j] << endl;
			}
			int n = j - 1;//cout << n;return 0;
			for (rint i = 1; i <= n; i++)
			{
				minn = min(minn, p[i] % x);
			}
			cout << minn << endl;
		}
	}
	
	return 0;
}

我们发现,这个题貌似并不需要用到数据结构。考虑两个优化:

  • 1.存储 ans[i] 表示 \(mod\) \(i\) 历次最小答案

  • 2.根号分治卡阈值

这个题就做完了,如果忘记根号分治详见浅谈根号分治

#include <bits/stdc++.h>

#define rint register int
#define endl '\n'

using namespace std;

const int N = 3e5 + 5;
const int M = 1e5 + 5;

int n, ans[M];
set<int> s;

int main() 
{
    for (rint i = 1; i <= M; i++)
    {
		ans[i] = i;
	}
	
	n = 1000;
	int T;
	cin >> T;
	
    while(T--)
	{
        char op; 
		int x;
        cin >> op >> x;
        if(op == 'A') 
		{
            for (rint i = 1; i <= n; i++)
            {
			    ans[i] = min(ans[i], x % i);		
			}
            s.insert(x);
        }
        else 
		{
            if(x < n) 
			{
				cout << ans[x] << endl;
			}
            else 
			{
                int res = x;
                for(int i = 0; i < N; i += x) 
				{
                    auto it = s.lower_bound(i);
                    if(it == s.end()) 
					{
						break;
					}
                    res = min(res, *it - i);
                }
                cout << res << endl;
            }
        }
    }
    
    return 0;
}

[NERC2018] Fractions

题目传送门
这个题的严格推导我并不会,但是我们可以手搓一下这个题相关的好玩的东西。

在做这个题之前,先把这个题改一下:

给你一个整数 \(n\),你需要构造出若干个形如 \(\dfrac{1}{b_i}\) 的真分数,使得 \(\sum^n_{i=1} \frac{1}{b_i} = \frac{n - 1}{n}\),且 \(b_i\) 可以整除 \(n\)。

无论是这个改的题还是原题,我们都可以很轻松的判断出,它必不为质数。

那我们举个例子,\(20\) 的因子有 \(2,4,5,10\), \(2 + 4 + 5 + 10 > 20 - 1\)那么 \(20\) 就一定可以拆成若干个几分之一的数相加。

所以只要一个数字的非自己和一的因数以外,如果加起来比它自己减一要大,那么就一定可以拆成若干个几分之一的数相加(瞎几把猜的)

那么能不能把这个结论扩展到这个题,让我们的每一个 \(a_i = 1\),好,显然不对。为什么?

因为必定存在一个数可以拆成别的情况的几个分数相加的形式,且分子不为一。

然后我又瞎搓搓出来一个正解算法。。。。。。

我们先来想两个问题。

第一个问题,我们拆出来的 \(b_i\) 是什么?一定是 \(n\) 的因子对不对。

再来想一个问题,我们既然可以把上面那个情况(改题)拆成若干个几分之一的数相加,那么是不是就可以将其中两个分数两两相加加成一直加加加加加到只剩两个分数相加?

我们之前无法用几个几分之一相加表示出来的数但是可以通过其他方式表示的数是不是也可以表示成两个分数相加?

抱着这样的猜想,我猜了一个结论:

如果这个数能拆,那么必然有一种拆解为两个分数相加,其中这两个分数的分母分别为 \(a\), \(n / a\)。\(a\) 为 n / 2或3或5..... 不断地除同一个质数

举个例子,\(45\) 先除以 \(3\) 再除以 \(3\) ,那么第一个分母为 \(9\),第二个分母为 \(5\),然后分子必为整数!虽然不会证明,但是它一定成立,因为过了。

代码如下

#include <bits/stdc++.h>

#define rint register int
#define endl '\n'

using namespace std;

int n;
int m;

signed main()
{
	cin >> n;
	m = n;
	
	for (rint i = 2; i * i <= n; i++)
	{
		if (!(m % i))
		{
			while(!(m % i))
			{
				m /= i;
			}
			break;
		}
	}
	/*
	    m 为 n 不断地除以它第一个因数
	*/
	if (m == 1 || m == n)//显然质数时不对
	{
		puts("NO");
		return 0;
	}
	
	int y = n / m;
	
	if(m > y) 
	{
		swap(m, y);
	}
	//cerr << m << " " << y;return 0;
	for(rint i = 1; i < m; i++)
	{
		int t = n - 1;
		if((t - y * i) % m == 0)
		{
			cout << "YES" << endl;
			cout << 2 << endl;
			cout << i << " " << m << endl;
			cout << (t - y * i) / m << " " << y;
			return 0;
		}
	}
	
	puts("NO");
	
	return 0;
}

「KDOI-06-J」贡献系统

题目传送门

给定一个数列 $c$,你需要给第 $i$ 个位置赋一个唯一排名 $b_i$,若 $b_i>i$,则将答案减去 $c_i$。若 $b_i<i$,则将答案加上 $c_i$,若相等,则什么都不做。求答案的最大值。


  • 当 $c_i>0$ 时,我们肯定希望 $i$ 的排名上升。
  • 当 $c_i<0$ 时,我们肯定希望 $i$ 的排名下降。
  • 当 $c_i=0$ 时,则排名任意。

先讨论 $c_i$ 全部大于 $0$ 的情况。

显然可以让第一名掉到最后一名,其他人顺次往前移一位。但这可能不是最优方案。

但是我们可以让 $1$ 至 $i$ 名保持不变,第 $i+1$ 名掉到最后一名,$i+2$ 到 $n$ 名顺次往前移($1\le i\le n$),这才是一种最优方案。


那么 $c_i$ 全部小于 $0$ 的情况也可以照样推出来,这里直接放结论:让 $i$ 至 $n$ 名保持不变,第 $i-1$ 名升到第一名,$1$ 到 $i-2$ 名顺次往后移($1\le i\le n$)。


现在考虑正解。

我们可以将原数列分成三部分:

第一部分:$1$ 到 $x-1$,里面全是正数。

第二部分:$y+1$ 到 $n$,里面全是负数。

第三部分:$x$ 到 $y$,里面有正有负有 $0$。($1\le x\le y\le n$)

对于第一、二部分,我们可以直接套用上面的结论。

对于第三部分,$c_x$ 必然是非正数,$c_y$ 必然是非负数。我们可以先让第 $x$ 位空出来,接着让所有正数顺次往前移,所有非正数往后移,你会发现刚好能移完(自己画个图就能懂)。也就是这一部分累加 $c_i$ 的绝对值即可。

#include <bits/stdc++.h>

#define rint register int
#define int long long
#define endl '\n'

using namespace std;

const int N = 2e5 + 5;

int T, n;
int c[N], s[N];
int ans1, ans2, ans3;
int sum;

int calc(int l, int r)
{
	return s[r] - s[l - 1];
}

signed main()
{
	cin >> T;
	while (T--)
	{
		ans1 = 0;
		ans2 = 0;
		ans3 = 0;
		cin >> n;
		for (rint i = 1; i <= n; i++)
		{
			int useless;
			cin >> useless;
			//这个题跟r就没关系
		}
		for (rint i = 1; i <= n; i++)
		{
			cin >> c[i];
			s[i] = s[i - 1] + abs(c[i]);
		}
		int x = 1, y = n;
		
		while (c[x] > 0 && x <= n) x++;
		while (c[y] < 0 && y >= 1) y--;
		
		for (rint i = 1; i < x; i++)
		{
			ans1 = max(ans1, calc(i + 1, x - 1) - c[i]);
		} 
		for (rint i = n; i > y; i--)
		{
			ans2 = max(ans2, calc(y + 1, i - 1) + c[i]);
		}
		ans3 = calc(x, y);
		sum = ans1 + ans2 + ans3;
		cout << sum << endl;
	}
	
	return 0;
}

标签:le,记录,int,rint,相加,2023.10,28,cin,define
From: https://www.cnblogs.com/spaceswalker/p/17794236.html

相关文章

  • git-清空历史提交记录(保留原仓库)
    0.备份进行操作之前,一定一定要先备份,你直接copy项目文件夹也行。1.创建一个新的孤立分支首先,创建一个新的孤立分支(没有历史记录)gitcheckout--orphannew-branch--orphan参数:孤立分支:使用--orphan创建的分支没有任何父提交记录,因此没有任何历史记录。这使得它看起......
  • 063java jsp ssm企业员工培训管理系统员工培训计划培训记录管理(源码+数据库+文档)
    项目技术:Spring+SpringMVC+MyBatis等等组成,B/S模式管理等等。环境需要1.运行环境:最好是javajdk1.8,我们在这个平台上运行的。其他版本理论上也可以。2.IDE环境:IDEA,Eclipse,Myeclipse都可以。推荐IDEA;3.tomcat环境:Tomcat7.x,8.x,9.x版本均可4.硬件环境:windows7/8/10......
  • Rocky Linux捣鼓记录(一):如何安装使用中文输入法
    linux的常见输入法方案有fcitx、ibus,fcitx类型的输入法我没找到合适方案,ibus提供了一个智能拼音中文输入法比较顺手,安装简单。我使用的系统版本为RockyLinux9.4,已经自带ibus中文输入法,从设置——keyboard中选择输入源,新增——汉语(中国)选择——中文(智能拼音)即可若系统中没有,......
  • 学习Angr记录--angr_ctf 00~05
    首先,下载angr_ctf,打开dist文件夹,这里才是练习题,然后solution是答案00.find01.avoid前面两个是基础操作复习一下流程:1.项目路径2.进入状态3.模拟器模拟进入状态时的环境4.模拟器explore,find一个地址,avoid一些地址5.simulation.found[]数组存储成功的输入6.print(solutio......
  • SQL学习记录 #1、入门:增删改查
    1. 通识SQL语句可以单行或多行书写,以分号结尾。SQL语句可以单独使用空格/缩进来增强语句的可读性。Mysql数据库的SQL语句不区分大小写,关键字建议使用大写。注释:单行注释:-- 注释内容或# 注释内容多行注释:/*注释内容*/2.分类分类概述说明DDL(DataDefinitionLangua......
  • 20240621维护记录
     dockerrun-d--namepause-1k8s.gcr.io/pause:3.2 注意:RunningError请看pods什么周期介绍https://www.jianshu.com/p/0bb8572e34f#!/bin/bashKEY=`cat/proc/sys/kernel/random/uuid`USER=`echo$KEY|cut-d"-"-f1`ACCESS_KEY=`uuidgen`SECRET_KEY=$KEYROLE_NAME......
  • DSP28335的ADC模块
    ADC模块一、ADC时钟分频 //使能ADC外设时钟EALLOW;SysCtrlRegs.PCLKCR0.bit.ADCENCLK=1;EDIS;//高速外设时钟HSPCLK=SYSCLKOUT/(2*HISPCP)=25MHzEALLOW;SysCtrlRegs.HISPCP.bit.HSPCLK=3;EDIS;//FCLK=HSPCLK/(2*ADCCLKPS)=12.5MHzAdcRegs.ADC......
  • python pyinstaller打包的exe 反编译问题记录 破解加密
    首先是用pyinstxtractor这个网上很多教程,不详说了。生成一个xxx.exe_extracted目录生成过程中,如果pyinstaller用key加密了,会[!]Error:FailedtodecompressPYZ-00.pyz_extracted\Cython\__init__.pyc,probablyencrypted.Extractingasis. 这个说是fail了,其实可以解......
  • TMS320F28335的ADC模块
    1 ADC简介英文全称Analog-to-DigitalConverter,模数转换器2 时钟配置外围时钟HSPCLK,通过HISCP来设置SysCtrlRegs.HISCP.all=3;设置为0时,不分频其他都为sysclk/2xHSPCLK=sysclk/(3*2)=150/6=25MHz此时还需要在进行一次分频通过设置ADCTRL3的ADCCLKP......
  • LangChain:如何高效管理 LLM 聊天历史记录?
    LangChain团队发布了一篇关于使用DragonflyDB来有效管理LangChain应用程序聊天历史记录的教程。该教程旨在解决用户在使用LangChain应用程序时普遍遇到的一个问题:如何高效地管理聊天历史记录。LangChain团队在推文中强调了DragonflyDB在管理聊天历史记录中的......