Shuffle UVA - 12174 尺取法

题目:题目链接

思路:见紫书,对具体操作方式还不是很理解,代码是从一个题解里看的,以后多回顾下,需要理解

代码:

 1 #include <iostream>
 2 #include <cstring>
 3 #include <set>
 4 using namespace std;
 5
 6 const int N = 1e5 + 5;
 7
 8 int s, n, a[N], vis[N];
 9 bool flag[N];
10 int ans;
11
12 void init()
13 {
14     cin >> s >> n;
15     int num = 0;
16     for (int i = 0; i < n; i++)
17     {
18         cin >> a[i];
19         if (i < s)
20         { //对前面的s个进行分析
21             if (vis[a[i]])
22                 num++; //统计前s个中重复的数字
23             vis[a[i]]++;
24         }
25     }
26
27     for (int i = 0; i < n; i++)
28     {
29         //如果num=0,说明前s个中没有重复的数字,那么第一个数字可以作为循环的开始
30         if (num == 0)
31             flag[i] = true;
32
33         //窗口开始滑动
34         if (vis[a[i]] == 2)
35             num--; //如果此时最左边的数为重复了的数,num需要减1
36         vis[a[i]]--;
37
38         int k = i + s; //新数字进入滑动窗口
39         if (k >= n)
40             continue;
41         if (vis[a[k]])
42             num++; //如果已经出现过
43         vis[a[k]]++;
44     }
45 }
46
47 bool judge(int x)
48 {
49     for (int i = x; i < n; i += s)
50         if (!flag[i])
51             return false;
52     return true;
53 }
54
55 void solve()
56 {
57     memset(vis, 0, sizeof(vis));
58
59     ans = 0;
60     for (int i = 0; i < s; i++)
61     {
62         if (judge(i))
63             ans++;
64         if (i >= n)
65             continue;
66         //从左往右依次遍历,如果当前a[i]前面已经出现过,那么前面必须会有开头,此时必须结束循环
67         if (vis[a[i]])
68             break;
69         vis[a[i]]++;
70     }
71 }
72
73 int main()
74 {
75     //freopen("D:\\txt.txt", "r", stdin);
76     int t;
77     cin >> t;
78     while (t--)
79     {
80         memset(flag, 0, sizeof(flag));
81         memset(vis, 0, sizeof(vis));
82         init();
83         solve();
84         cout << ans << endl;
85     }
86     return 0;
87 }

原文地址:https://www.cnblogs.com/fan-jiaming/p/9860519.html

时间: 2024-08-29 08:34:17

Shuffle UVA - 12174 尺取法的相关文章

Uva Galaxy(尺取法)

题意:n颗行星,给出每个点的一维坐标,可以删去m个点,使剩下所有点到剩余点集中心的距离的平方的和最小,求该最小值: 思路:尺取法,每次维护n-m个点:long long用%lld读入,但codeblocks编译会出现问题,所以用cin>>: #include<cstdio> #include<cstdlib> #include<cmath> #include<cstring> #include<algorithm> using nam

UVA 11990 `Dynamic&#39;&#39; Inversion CDQ分治, 归并排序, 树状数组, 尺取法, 三偏序统计 难度: 2

题目 https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=3141 题意 一个1到n的排列,每次随机删除一个,问删除前的逆序数 思路 综合考虑,对每个数点,令value为值,pos为位置,time为出现时间(总时间-消失时间),明显是统计value1 > value2, pos1 < pos2, time1 < time2的个

UVA 12174 Shuffle(滑动窗口)

T*n已经最大已经是10的7次方了,所以这道题虽然暴力枚举前面不完整歌单的情况的思路好想,但是必须用滑动窗口(或者叫尺取法)的技巧来预处理两个数组,这样可以O(n)完成每组数据. #include<iostream> #include<cstdio> #include<cstdlib> #include<cstring> #include<string> #include<cmath> #include<map> #inc

luogu 1712 区间(线段树+尺取法)

题意:给出n个区间,求选择一些区间,使得一个点被覆盖的次数超过m次,最小的花费.花费指的是选择的区间中最大长度减去最小长度. 坐标值这么大,n比较小,显然需要离散化,需要一个技巧,把区间转化为半开半闭区间,然后线段树的每一个节点表示一个半开半闭区间. 接着我们注意到需要求最小的花费,且这个花费只与选择的区间集合中的最大长度和最小长度有关. 这意味着如果最大长度和最小长度一定,我们显然是需要把中间长度的区间尽量的选择进去使答案不会变的更劣. 不妨把区间按长度排序,枚举每个最小长度区间,然后最大区间

poj 3320 Jessica&#39;s Reading Problem(尺取法+map/hash)

题目:http://poj.org/problem?id=3320 题意:给定N个元素的数组,找出最短的一段区间使得区间里面的元素种类等于整个数组的元素种类. 分析:暴力枚举区间的起点x,然后找到最小的y,使得区间[x,y]满足条件,x向有移位后变成x',现在的y'肯定不至于在y的左边.存状态的话map和hash都可以. map代码: #include <iostream> #include <set> #include <map> #include <cstdi

hihocoder-1483区间价值 (二分+尺取法)

题目链接: 区间价值 给定n个数A1...An,小Ho想了解AL..AR中有多少对元素值相同.小Ho把这个数目定义为区间[L,R]的价值,用v[L,R]表示. 例如1 1 1 2 2这五个数所组成的区间的价值为4. 现在小Ho想知道在所有的的v[L,R](1 <= L <= R <= n)中,第k小的值是多少. Input 第一行一个数T(T<=10),表示数据组数. 对于每一组数据: 第一行两个数n,k(1<=n<=200,000,1<=k<=n*(n+1

【转】毛虫算法&mdash;&mdash;尺取法

转自http://www.myexception.cn/program/1839999.html 妹子满分~~~~ 毛毛虫算法--尺取法 有这么一类问题,需要在给的一组数据中找到不大于某一个上限的"最优连续子序列" 于是就有了这样一种方法,找这个子序列的过程很像毛毛虫爬行方式,我管它叫毛毛虫算法,比较流行的叫法是"尺取法". 喏,就像图里的妹纸一样~ 还是举个栗子: Poj3061 给长度为n的数组和一个整数m,求总和不小于m的连续子序列的最小长度 输入 n = 1

51nod1127(尺取法)

题目链接:https://www.51nod.com/onlineJudge/questionCode.html#!problemId=1127 题意:中文题诶- 思路:尺取法 维护一个队列,若当前队首的元素在后面出现了,那么我们就将其删除,若当前队列里含有26个字母,我们就记录其size. 取所有size里面的最小值就是我们要的答案... 代码: 1 #include <iostream> 2 #include <stdio.h> 3 #include <string>

BestCoder Round #86 二,三题题解(尺取法)

第一题太水,跳过了. NanoApe Loves Sequence题目描述:退役狗 NanoApe 滚回去学文化课啦! 在数学课上,NanoApe 心痒痒又玩起了数列.他在纸上随便写了一个长度为 nnn 的数列,他又根据心情随便删了一个数,这样他得到了一个新的数列,然后他计算出了所有相邻两数的差的绝对值的最大值. 他当然知道这个最大值会随着他删了的数改变而改变,所以他想知道假如全部数被删除的概率是相等的话,差的绝对值的最大值的期望是多少. 输入描述 第一行为一个正整数 T,表示数据组数. 每组数