【loli的胡策】测试3.26 (贪心+hash)

本文分享了作者在解决两道编程题目的过程中所遇到的问题及解决方案。对于第一题,作者最初尝试使用二分查找方法但未果,最终采取了一种更直接的策略取得了成功。第二题则通过发现循环规律并利用哈希进行状态判别,有效减少了计算量。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

T1

这里写图片描述
这里写图片描述

题解:

今天的T1犯了经验主义的错误,一眼二分之后死在了寻找答案的路上。
其实并不需要二分,考虑每次删除出现次数最多的项目,每次更新最小值获得答案,时间复杂度O(nm)O(nm)

代码:

#include <cstdio>
#include <iostream>
using namespace std;
const int N=1005;
int a[N][N],mid,m,n,f[N],up[N];bool vis[N];
int main()
{
    freopen("sports.in","r",stdin);
    freopen("sports.out","w",stdout);
    scanf("%d%d",&n,&m);
    for (int i=1;i<=n;i++) 
      for (int j=1;j<=m;j++) scanf("%d",&a[i][j]);
    for (int i=1;i<=n;i++) f[a[i][1]]++,up[i]=1;
    int ans=n;
    for (int now=1;now<m;now++)
    {
        int maxx=0;
        for (int i=1;i<=m;i++)
          if (f[i]>f[maxx]) maxx=i;
        vis[maxx]=1;
        for (int i=1;i<=n;i++)
          if (a[i][up[i]]==maxx) 
          {
            f[maxx]--;up[i]++;
            while (vis[a[i][up[i]]]) up[i]++;
            f[a[i][up[i]]]++;
          }
        maxx=0;
        for (int i=1;i<=m;i++) maxx=max(maxx,f[i]);
        ans=min(ans,maxx);
    }
    printf("%d",ans);
}

T2

这里写图片描述
这里写图片描述

题解:

这个题目可以发现一个点分别关于两个点概率相等的期望是整数点,即a[i+1]+a[i-1]-a[i],(随便画个长度的柿子就可以),所以根本不会出现什么小数
根据期望的线性,我们完全可以暴力O(km)O(km)来完成跳跃过程,期望得分40
然后我对于跳完n次的青蛙期望位置打了个表,发现ta给的前两个样例都有循环节这个东西,而且都离的很近
那么我们可以考虑找循环节,用hash判重,这样只需要模拟k%xhj的大小就好了,期望得分70

#include <map>
#include <cmath>
#include <cstdio>
#include <algorithm>
#define LL long long
#define ull unsigned long long
using namespace std;
map<ull,bool>have;
const int N=100005;
const ull mod=212370440130137957ull;
int h[N];LL a[N];
int main()
{
    freopen("frog.in","r",stdin);
    freopen("frog.out","w",stdout);
    int n,m;LL k,hs=0;scanf("%d",&n);
    for (int i=1;i<=n;i++) scanf("%lld",&a[i]),hs=(hs*10+a[i])%mod;
    have[hs]=1;
    scanf("%d%lld",&m,&k);LL xh=k;
    for (int i=1;i<=m;i++) scanf("%d",&h[i]);
    if (k<=1000 && m<=1000)
    {
        for (int i=1;i<=k;i++)
          for (int j=1;j<=m;j++) a[h[j]]=a[h[j]+1]-a[h[j]]+a[h[j]-1];
        for (int i=1;i<=n;i++) printf("%lld\n",a[i]);               
    }
    else
    {
        for (LL i=1;i<=k;i++)
        {
            for (int j=1;j<=m;j++) a[h[j]]=a[h[j]+1]-a[h[j]]+a[h[j]-1];
            LL hs=0;
            for (int j=1;j<=n;j++) hs=(hs*10+a[j])%mod;
            if (have[hs]) {xh=i;break;}
            have[hs]=1;
        }
        int xx=k%xh;if (!xx) xx=xh;
        for (int i=1;i<=xx;i++)
          for (int j=1;j<=m;j++) a[h[j]]=a[h[j]+1]-a[h[j]]+a[h[j]-1];
        for (int i=1;i<=n;i++) printf("%lld\n",a[i]);       
    }
}

小结:

这两天的胡策都反映出一个问题,就是对于算法的第一臆断。一看到题目就认定是某种算法然后死刚不停。昨天的前两道题目和今天的T1都是这样的,以后应该跳出局限性,一条路走不通就想想别的方法。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值