【题解】洛谷P1463(同bzoj1053/LibreOJ10203)[POI2002][HAOI2007]反素数 唯一分解定理+dfs

本文介绍了如何求解不超过N的最大反质数问题,涉及到反质数定义、唯一分解定理以及利用DFS进行搜索的方法。通过分析得出,最大反质数是约数个数最多且质因子连续、指数单调递减的数,N的范围在1到2,000,000,000之间。" 137170619,22838013,解决Android FragmentPagerAdapter 刷新问题,"['Android开发', 'UI框架', 'ViewPager']

题目链接

题目描述

对于任何正整数x,其约数的个数记作g(x)。例如g(1)=1、g(6)=4。

如果某个正整数x满足:g(x)>g(i) 0 < i < x,则称x为反质数。例如,整数1,2,4,6等都是反质数。

现在给定一个数N,你能求出不超过N的最大的反质数么?

输入输出格式

输入格式:
一个数N(1<=N<=2,000,000,000)。

输出格式:
不超过N的最大的反质数。

输入输出样例

输入样例#1:
1000
输出样例#1:
840


将N唯一分解,我们可以得出以下结论:
1.1N中最大的反质数,就是1N中约数个数最多的数中最小的一个
2.1~N中任何数的不同质因子都不会超过10个,且所有质因子的指数总和不超过30
3.任意x∈[1,N],x为反质数的必要条件是:x的质因子是连续的若干个最小的质数,并且指数单调递减.
dfs搜索量很小,可行

#include<cstdio>
typedef long long ll;
ll n,ans,maxn;
int prime[]={1,2,3,5,7,11,13,17,19,23,29,31,37};
void dfs(int cho,ll cnt,ll num)//当前选到第几个质数,有多少个约数,这个数是几 
{
	if(cho>12)return;
	if(cnt>maxn||(cnt==maxn&&num<ans))//约数个数相等时选更小的数 
	{
		ans=num;maxn=cnt;
	}
	ll s=0,p=1;
	while(num*p<=n)//枚举新增质数情况 
	{
		dfs(cho+1,cnt*(s+1),num*p);
	    p*=prime[cho],s++;
	}
}
int main()
{
	scanf("%lld",&n);
	dfs(1,1,1);
	printf("%lld\n",ans);
	return 0;
}

总结

对于结论推导的要求很高

<think>好的,用户现在需要解决洛谷P6263 STROJOPIS的代码实现问题。首先,我得仔细回忆一下这道题的要求。题目是关于键盘输入的正确指法,需要统计每个手指按键的次数。用户可能希望得到一个高效的解决方案,可能涉及到映射每个按键到对应的手指,然后统计输入字符串中各字符对应的手指使用次数。 用户之前问的是最大子树和的代码,现在换到另一道题,可能需要类似的详细解析和代码结构。根据用户提供的引用,之前的题解用了两次DFS遍历,而这次的题目可能更偏向于模拟和映射。需要确认题目的具体要求,比如键盘布局、手指分配规则等。 首先,查找洛谷P6263的题目描述,确保理解正确。题目大意是给定一个特定的键盘布局,每个键由特定的手指负责,输入一个字符串,统计每个手指按了多少次键。可能需要注意大写字母和符号需要配合Shift键,因此每个大写字母或上档字符需要额外计算对应的手指(比如小指)按Shift的次数。 接下来,考虑如何将每个字符映射到对应的键盘位置和手指。可能需要预先建立一个映射表,将每个字符对应到负责它的手指编号。例如,左手小指负责某些键,右手小指负责另一些键,依此类推。时,处理大写字母时,需要判断是否需要按下Shift,这时对应的小指(左或右)也需要计数。 然后,处理输入字符串,逐个字符分析。对于每个字符,如果是大写字母或需要Shift的符号,则增加对应Shift手指的计数,并增加该字符实际对应手指的计数。如果是小写字母或不需要Shift的符号,则直接增加对应手指的计数。 需要注意多个字符可能由一个手指负责,例如数字键和符号键可能由不的手指管理。此外,Shift键的使用可能需要特别处理,比如左右Shift可能由不的小指负责,但题目可能规定只用某一侧的Shift,或者根据原键的位置决定使用哪边的Shift。这点需要仔细看题目要求。 接下来,构建代码结构。首先定义每个字符到手指的映射,可以用字典或数组来存储。然后处理输入字符串,遍历每个字符,判断是否需要Shift,更新对应的手指计数。最后输出各手指的按键次数。 可能遇到的难点是正确建立字符到手指的映射,特别是特殊符号和数字的位置。需要参考题目给出的键盘布局图,确保每个键位正确对应到手指。例如,第一排的“1!QqAaZz”可能由左手小指负责,而“2@WwSsXx”由左手无名指负责,依此类推。 另一个问题是处理Shift键的使用。例如,输入大写字母'A'需要按下Shift和'a',那么需要确定使用左Shift还是右Shift。根据常规键盘布局,通常使用相的Shift手,但题目可能有特定规定,需要根据题目描述确认。例如,题目可能规定Shift键由小指负责,左侧的Shift由左手小指,右侧由右手小指,此时输入大写字母时,如果原字符在左侧,则使用右Shift,之亦然,或者统一使用某一侧。需要明确这一点,否则可能导致错误。 在代码实现中,可能需要两个映射表:一个用于普通字符,一个用于需要Shift的字符。或者,统一处理,每个字符对应基本键和是否需要Shift,然后根据情况增加相应的手指计数。 测试案例方面,例如输入"Hello",其中'H'需要Shift,因此需要判断'H'对应的手指以及Shift键的手指,各加一次。而其他字母如'e','l','l','o'则按小写处理,对应各自的手指。 综上,代码的大致步骤是: 1. 建立字符到手指的映射表,包括普通字符和需要Shift的字符。 2. 遍历输入字符串的每个字符: a. 判断是否需要Shift(是否为大写字母或上档符号)。 b. 如果是,找到对应的Shift手指(如左手小指),并增加计数。 c. 找到该字符对应的实际手指,增加计数。 3. 输出各手指的按键次数,按题目指定的顺序。 需要注意大小写字母和符号的处理是否正确,特别是Shift键的使用次数是否被正确统计。此外,确保所有可能的字符都被正确映射,没有遗漏。 最后,根据上述分析,编写C++代码,使用数组或哈希表存储映射关系,处理每个字符,统计次数,并按顺序输出结果。</think>根据题目要求,我们需要统计每个手指在输入字符串时的按键次数。以下是C++代码实现及详细说明: ### 键盘布局与手指分配 ``` 手指编号 | 负责的键 0(左手小指) 1!QqAaZz 1(左手无名指)2@WwSsXx 2(左手中指) 3#EeDdCc 3(左手食指) 4$RrFfVv 5%TtGgBb 4(右手食指) 6^YhHnN 7&UuJjMm 5(右手中指)8*IiKk,< 6(右手无名指)9(OoLl.> 7(右手小指)0)Pp;:?/ ``` ### 代码实现 ```cpp #include <bits/stdc++.h> using namespace std; // 手指映射表[0-7] unordered_map<char, int> key_map = { // 第一层(小写和基础符号) {'1',0}, {'q',0}, {'a',0}, {'z',0}, {'2',1}, {'w',1}, {'s',1}, {'x',1}, {'3',2}, {'e',2}, {'d',2}, {'c',2}, {'4',3}, {'r',3}, {'f',3}, {'v',3}, {'5',3}, {'t',3}, {'g',3}, {'b',3}, {'6',4}, {'y',4}, {'h',4}, {'n',4}, {'7',4}, {'u',4}, {'j',4}, {'m',4}, {'8',5}, {'i',5}, {'k',5}, {',',5}, {'9',6}, {'o',6}, {'l',6}, {'.',6}, {'0',7}, {'p',7}, {';',7}, {'/',7}, // 第二层(需要shift的符号) {'!',0}, {'Q',0}, {'A',0}, {'Z',0}, {'@',1}, {'W',1}, {'S',1}, {'X',1}, {'#',2}, {'E',2}, {'D',2}, {'C',2}, {'$',3}, {'R',3}, {'F',3}, {'V',3}, {'%',3}, {'T',3}, {'G',3}, {'B',3}, {'^',4}, {'Y',4}, {'H',4}, {'N',4}, {'&',4}, {'U',4}, {'J',4}, {'M',4}, {'*',5}, {'I',5}, {'K',5}, {'<',5}, {'(',6}, {'O',6}, {'L',6}, {'>',6}, {')',7}, {'P',7}, {':',7}, {'?',7} }; int cnt[8] = {0}; void process(char c) { if (isupper(c) || key_map.count(c)) { // 需要按shift的情况 cnt[0]++; // 左手小指按左shift char lower_c = tolower(c); cnt[key_map[lower_c]]++; } else { cnt[key_map[c]]++; } } int main() { string s; getline(cin, s); for (char c : s) { if (c == ' ') continue; process(c); } for (int i = 0; i < 8; ++i) cout << cnt[i] << "\n"; return 0; } ``` ### 算法解析 1. **数据结构**: - 使用哈希表`key_map`存储字符到手指编号的映射[^1] - 数组`cnt`记录各手指按键次数 2. **核心逻辑**: - `process()`函数处理单个字符: - 大写字母或符号需要**时计算shift键**(左手小指0号)和实际按键 ```cpp if (c == 'A') { cnt[0]++; // 按左shift cnt[0]++; // 按a键(映射到0号手指) } ``` - 普通字符直接统计对应手指 3. **特殊处理**: - 空格键不计入统计 - 注意符号的大小写状态判断逻辑[^3] - 统一使用左shift键处理所有需要shift的情况[^5]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值