『UVA 12174』Shuffle (滑动窗口+技巧记录暴力)

转载声明:http://blog.csdn.net/keshuai19940722/article/details/19292045
个人想法:这道题几乎花了我一天的时间,想出算法来,可是无情的wa了,自己想了想例子
(4 8)
(3 2 4 1 3 2 3 2) 直接把我的想法推倒,简直无力,无奈的请教题解了,我转载的这篇文章是我看到写法比较清晰的文章了.先说说我的想法吧, 首先我一看到连续的 我会自动想到滑动窗口, 可是我的算法会划分出【3 2 4 1】【3 2】【3 2】 这样的就是错误的 因为 对于一串数字是否合法, 我认为只会出现这样的情况 假设 [唯一] 代表 满足s,而且里面的数字都是唯一的窗口, 【不唯一】代表 不满足s 但数字是唯一的窗口,那么无非就是 【不唯一】/[唯一] +[唯一]* +(【不唯一】/[唯一])^(0…1) 个这样组成的数字串,凡是不符合这个公式的串 都不合法, 可能是我算法用了贪心的原因,我在分析数字串结构式就分析出来这样的方式,果断wa…

分析:首先用滑动窗口在o(n) 时间内求出 以i为开头的连续s个的序列中是否满足都是[唯一]的,然后枚举前s个开头,如果 i+=s ,i<=n的所有区间都满足[唯一]性,则当前位置可以划分.我感觉这个技巧好有意思啊…太蠢了居然没想到。

代码:

/* Author:GavinjouElephant
 * Title:
 * Number:
 * main meanning:
 *
 *
 *
 */

//#define OUT
#include <iostream>
using namespace std;
#include <cstdio>
#include <cmath>
#include <cstring>
#include <algorithm>
#include <sstream>
#include <cctype>
#include <vector>
#include <set>
#include <cstdlib>
#include <map>
#include <queue>
//#include<initializer_list>
//#include <windows.h>
//#include <fstream>
//#include <conio.h>
#define MaxN 0x7fffffff
#define MinN -0x7fffffff
#define Clear(x) memset(x,0,sizeof(x))
const int INF=0x3f3f3f3f;
const int maxn=100000+10;
int s,n;
int T;
int p[maxn],c[maxn];
bool flag[maxn];
void init()
{
    memset(flag, 0, sizeof(flag));
    memset(c, 0, sizeof(c));
    scanf("%d%d",&s,&n);
    int tmp=0;
    for(int i=0;i<n;i++)
    {
        scanf("%d",&p[i]);
        if(i<s)
        {
            if(c[p[i]])tmp++;
            c[p[i]]++;
        }
    }
    for (int i = 0; i < n; i++)
    {
        if (tmp == 0) flag[i] = true;

        if (c[p[i]] == 2) tmp--;
        c[p[i]]--;

        int k = i + s;
        if (k >= n) continue;
        if (c[p[k]]) tmp++;
        c[p[k]]++;
    }
}

bool judge(int x)
{
    for(int i=x;i<n;i+=s)  if(!flag[i])return false;
    return true;
}
int solve()
{
    int ans=0;
    memset(c,0,sizeof(c));
    for(int i=0;i<s;i++)
    {
        if(judge(i))ans++;
        if(i>=n) continue;
        if(c[p[i]])break;
        c[p[i]]++;
    }
    return ans;
}
int main()
{
#ifdef OUT
    freopen("coco.txt","r",stdin);
    freopen("lala.txt","w",stdout);
#endif
    scanf("%d",&T);
    while(T--)
    {
        init();
        printf("%d\n",solve());
    }
    return 0;
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值