CF352B题解

对于我这种蒟蒻都能一遍 AC 的水题嘛,我要不然放个代码就跑吧~~~

算了,还是老老实实分析题意。

对于 如此小的可怕的数据范围,显然我们可以开一个结构体,分别存储每个元素在数组里出现的上一个数的位置,等差数列的,这个数出现的次数和当前成立与否。

然后 O(n) 扫一遍,特判一下某个数第一次和第二次出现一定成立就好。

最后 O(n) 扫两遍,分别统计成立数字的个数,然后再输出。

具体实现看代码,自以为注释挺详细的。

#include<iostream>
using namespace std;
int n, maxn;
int a[100005];
struct Node{
    int last;//上一个数是几
    int cha;//等差数列的差是几
    int num;//这个数出现了几次 
    bool flag = true;//这个数成立与否 
}ans[100005];
int main() {
    scanf("%d",&n);
    for(int i = 1; i <= n; i++){
        scanf("%d", &a[i]);
        maxn = max(maxn, a[i]);//找到最大的a[i] 
    }
    for(int i = 1; i <= n; i++){
        if(ans[a[i]].flag == false)//在之前的判断中已经不成立了
            continue;//直接退出 
        else if(ans[a[i]].num == 0)//这个数是第一次出现
            ans[a[i]].last = i,//起始位置是i
            ans[a[i]].num++,
            ans[a[i]].cha = 0; 
        else if(ans[a[i]].num == 1){//有一个数了,是第二次出现
            ans[a[i]].cha = i - ans[a[i]].last,//标记差值 
            ans[a[i]].last = i,//标记元素 
            ans[a[i]].num++;//个数++ 
        }
        else{//出现过多次了 
            if(i - ans[a[i]].last != ans[a[i]].cha)//不成立 
                ans[a[i]].flag = false;//此时不用做别的处理,因为!flag后都没有意义了 
            else
                ans[a[i]].last = i,//继续更新 
                ans[a[i]].num++;
        }
    }
    int cnt = 0;
    for(int i = 1; i <= maxn; i++)
        if(ans[i].num && ans[i].flag)
            cnt++;
    printf("%d\n",cnt);
    for(int i = 1; i <= maxn; i++)
        if(ans[i].num && ans[i].flag)
            printf("%d %d\n", i, ans[i].cha);
    return 0;
}

不是,你分析思路跟没分析一样

posted @   长安19路  阅读(12)  评论(0编辑  收藏  举报  
相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现
点击右上角即可分享
微信分享提示