思路:
定义三个 unordered_map,两个 unordered_map 的键和值都是 int 类型,分别存被访问的次数定义名字为 mpmpmp 和是在什么时候存进来的定义名字为 jljljl,第三个 unordered_map 的键为 int 类型,而值为 vector 数组,用来存访问次数为键的内存页是几定义名字为 sesese。
定义 ccc 为需要访问的虚拟内存页的编号,再定义一个 minnminnminn 表示现在最少的访问次数。
如果要访问的内存页存在也就是 mp.count(c) 为一,那么让我们的答案加一,然后把 sesese 里的数组里的 ccc 删除,接着把 ccc 加入到 sesese 的键为这次操作后 ccc 被访问的次数的数组里,然后判断一下在这次操作后原本 sesese 的键为 minnminnminn 的数组大小是否为零,如果为零则代表 ccc 原本是这个数组里唯一的元素,而 ccc 的访问次数增加后,这个数组里就没有元素了,也就是最少的访问次数现在不是 minnminnminn 了而是 minnminnminn 加上一,我们让 minnminn ...
思路:
看题,需要在矩阵上找出一条起始点任意的路径(可以重复经过某个格子),使得字典序最大。
那么通过可以重复这四个字我们可以知道最后求出的字符串的长度一定是小于等于二的。
所以,我们可以在输入时查找最大的字母(为了保证字典序最大)用一个变量 ccc 存下来,输入完之后,历遍矩阵,当历遍到的字母为我们找到的最大的字母时,查找他上下左右四个方向的最大的字母,然后用 chchch 存下来。
最后在循环结束后在 ccc 与 chchch 不相同时输出 chchch 就可以了,相同的情况就不要输出了。
代码:
#include<bits/stdc++.h>using namespace std;#define LL long long#define itn int#define ull unsigned long long int n,m;char ch;char jz[1500][1500]; int dx[]={1,-1,0,0},dy[]={0,0,-1,1};int main(){ int mx=0,my=0; ch ...
思路:
直接按照题目进行模拟输出,题目有公式,可以直接看下面的公式,在输入后套公式输出就行了。
代码:
#include<bits/stdc++.h>using namespace std;#define LL long long#define itn int#define ull unsigned long longconst double j=sqrt(3)/2;int main(){ LL x,y;cin>>x>>y; printf("%.6lf %.6lf",0.5*x+0.5*y,j*x-j*y); return 0;}
思路:
使用 dfs 算法,创建一个数组存当前已经找到的数字。
深度优先搜索代码实现:传入的量为现在找的是第几个数,第一次传入的是一,表示现在找的是第一个数,当传入的数减一等于 mmm 时输出。
输出函数实现:循环定义的 iii 表示当前已经找到的数字的数组的下标,如果你下标是从零开始存的就从零历遍到 m−1m-1m−1,如果是从一开始存的就从 111 历遍到 mmm,注意不要忘了最后换行。
因为题目中要求字典序较小的排在前面,所以我们就不定义标记数组了,下一次搜索就直接从上一个数加一开始。
完整代码:
#include<bits/stdc++.h>using namespace std;#define LL long long#define itn int#define ull unsigned long longull n,m;ull sc[30];// 存现在找到的数字void print(){// 输出 for(int i=1;i<=m;i++)cout<<sc[i]<<" "; cout<&l ...
思路:
使用前缀和,考虑到输入的询问范围可能会有 lll 相同,所以先用一个结构体把输入的 lll 和 rrr 和输入的顺序存起来,然后进行排序哪个左端点更小,如果同时左端点相同,那么比较哪个右端点更小。
在 lll 相等时,我们可以直接按照上一个的答案往下搜这样重复的部分就不用重复计算历遍了。
为什么可以直接按照上一个的答案往下搜,因为我们在一开始排过序,只要这个结构体排完序后在前一个结构体后面,并且 lll 相同,那么后面的结构体的 rrr 一定大于等于前面的结构体的 rrr,所以可以直接按照上一个的答案往下搜。
当 lll 不相等时,就正常地直接历遍,然后存答案就可以了。
完整代码:
#include<bits/stdc++.h>using namespace std;#define ull unsigned long long#define LL long longull tamp;const int MAXN=10001;const int MAXQ=1000001;ull n,q;ull sum[MAXN];ull a[100010];struct nod ...
思路:
因为只有通过删除一个字符,或插入一个字符,或修改一个字符变成另一个字符串才是相似的,所以我们可以分成五种情况。
第一种情况,如果第一个字符串和第二个字符串是相同的,那么这两个字符串是相似的,代码如下。
if(a==b){// 特判如果 a 与 b 相同的情况 cout<<"similar\n";continue;}
第二种情况,如果第一个字符串的长度等于第二个字符串的长度且两个字符串不相同,如果它们是相似的,那么只能是修改一个字符出来的,两个字符串之间至少有第一个字符串的长度减一个字符是相同的,且位置相同,代码如下。
if(a.size()==b.size()){// a 的长度与 b 的长度相同 for(int i=0;i<a.size();i++){ if(a[i]==b[i])cnt++;// 都用 i 因为要在同一个位置 } if(cnt+1==a.size()||cnt==a.size()){// 至少有 a.size()-1 个字符相同且在同一个位置 co ...
思路:
先写出暴力的搜索,然后改为记忆化搜索。
暴力的搜索就是暴力向下搜 nnn 减去 aaa 和 nnn 减去 bbb 的游戏操作序列的总数,暴力搜索代码如下。
long long dfs(long long x){ if(x<=c)return 1; return (dfs(x-a)%mod+dfs(x-b)%mod)%mod;}
然后改为记忆化搜索,定义一个数组存结果,如果现在搜索的这个数已经被搜索过了就自己访问数组,如果没有就先搜索,搜索完后赋值,这样就可以防止重复地搜索一个数,记忆化搜索代码如下。
long long dfs(long long x){ if(x<=c)return 1; if(an[x]!=0)return an[x];// 如果有值直接返回 return an[x]=(dfs(x-a)%mod+dfs(x-b)%mod)%mod;// 如果没有进行搜索并赋值}
完整代码:
#include<bits/stdc++.h>using namespace std;long long an[20 ...
思路:
考虑到 nnn 的最大值只有九,所以可以使用 dfs 算法枚举组合方案,把每一头牛的放置顺序存入一个数组中,当把所有的牛都放好后,算出需要的牛棚,最后输出最小值就可以了。
如何算出需要的牛棚,先画张图。
观察这张图,可以分四种情况。
第一种情况,上一头牛的 bbb 大于现在这头牛的 aaa,那么距离是上一头牛的 bbb,如下图。
第二种情况,上一头牛的 bbb 等于现在这头牛的 aaa,那么这两个数都可以是距离,如下图。
第三种情况,上一头牛的 bbb 小于现在这头牛的 aaa,那么距离是这头牛的 aaa,如下图。
第四种情况,没有上一头牛,也就是第一头牛,没有距离,循环直接从第二个放入牛的开始,如下图。
通过上述分析可以看出,距离是上一头牛的 bbb 与这头牛的 aaa 中的最大值。
需要注意的是求完距离后要考虑这一头牛也需要一个牛棚,所以每次求出距离后还要加一才可以算出需要的牛棚,要提前处理第一头牛,可以直接将求需要的牛棚的变量赋值为一。
完整代码带注释:
代码与思路完全相同。
#include<bits/stdc++.h>using names ...
思路:
定义一个数组存这个数最大的质因数。
如何存,枚举每一个小于 nnn 的质数,再枚举它的倍数,但是在枚举倍数时要注意如果第二个数字大于了第一个数字且第二个数字是质数那么先跳过,且第一个数字乘第二个数字要是大于 nnn 那么退出这一层循环写进判断条件里,代码如下。
for(long long i=2;i<=n;i++){ if(zs(i))//注意 i 要是质数 for(long long j=1;j*i<=n;j++){//枚举 i 的倍数 if(j>i&&zs(j))continue;// 如果 j 大于 i 且 j 是质数 那么说明 i*j 这个数的最大质因数不是 i 直接跳过后面再赋值 bj[j*i]=i; //cout<<i*j<<"\n";// 测试 } else continue;//i 不是质数跳过 }
标记好了后,定义一个存的变量变量赋值为一,因为虽然一没有质因数但是还是要加上,然后枚举从二到 nnn 中有多少个的最大质因数 ...
思路:
规律:观察后发现答案是每种邮票的张数除以现在的人数后省去小数部分后再次乘以人数。
每种邮票的张数除以现在的人数后省去小数部分就是可以分成几组,组不能是小数,因为题中说申请人都必须从该城市获得相同数量的邮票所以不能分开。
再乘以人数就是求分出了几张邮票。
一开始想用桶但发现数据太大了开不了数组,所以用了 map 但是用了 map 后发现不能满分于是观察了下发现只要有一个的邮票发出总和为零时,后面的也都是零,这样过后发现还是不可以满分,再次观察题目发现是不需要排序的,所以把 map 改成 unordered_map 就这样了吗,没有,再次观察可以发现当一个邮票的张数已经小于现在的人数了,那么不管怎么样,后面都不可以让答案增加了,所以直接删去,这样就可以了。
代码:
#include<bits/stdc++.h>using namespace std;unordered_map<int,int>mp;int n;int main(){ ios::sync_with_stdio(0); cin.tie(0);cout.tie(0); cin> ...
![题解:P2318 [HNOI2005] 虚拟内存](https://fastly.jsdelivr.net/npm/xyx404blogphoto@1.0.3/img/wenz/P2318.jpg)

![题解:P10520 [XJTUPC2024] 榕树之心](https://fastly.jsdelivr.net/npm/xyx404blogphoto@1.0.3/img/wenz/P10520.jpg)


![题解:B3958 [GESP202403 四级] 相似字符串](https://fastly.jsdelivr.net/npm/xyx404blogphoto@1.0.3/img/wenz/B3958.jpg)
![题解:P10376 [GESP202403 六级] 游戏](https://fastly.jsdelivr.net/npm/xyx404blogphoto@1.0.3/img/wenz/P10376.jpg)
![题解:P10377 [GESP202403 六级] 好斗的牛](https://fastly.jsdelivr.net/npm/xyx404blogphoto@1.0.3/img/wenz/P10377.jpg)
![题解:B3969 [GESP202403 五级] B-smooth 数](https://fastly.jsdelivr.net/npm/xyx404blogphoto@1.0.3/img/wenz/B3969.jpg)
![题解:P10355 [PA2024] Znaczki pocztowe](https://fastly.jsdelivr.net/npm/xyx404blogphoto@1.0.3/img/wenz/P10355.jpg)

