-TEST 15 for NOIP 决策有毒(150-300)

头更更大

这个10月完就要去搞NOIP了。。。

10月30天也就3次测试。。。为保佑进省一我还是每次测试玩都写个总结。。


。。。第三题炸了10分。。还能接受。
第一题水题再不AC我可以去冰箱里拿面包了。
第二题。。决策Dp套路。。。忘了(明明是你没复习
第三题暴力,还比较可观。。拿了50分

从本周开始凡是比赛模板禁用!!

下面面详细解答:

T1(100/100):比赛

problem

题意:给你一个数组a[i]和一个数k,定义任意i!=j,如果| a[i]-a[j] |>k那么两个数中较小的被淘汰,否则从两个数中任意淘汰一个数,问你最后剩余的数可能有几个(就是数组中有多少个下标不同的数会是最后一个)
样例

  • 输入
    2
    4 3
    1 9 6 2
    5 2
    1 5 9 6 3

  • 输出
    2
    1

solution

专门说得这么拗口其实就是想让你栽进输出排序后第一个a[i]满足a[n]<=a[i]+k的。
但是想一想就知道这个解法的反例:假设数列是1~10,k值为2,那么答案应该是10而不是3。
所以正解就是从后往前一次比较相邻的两个数的差的绝对值是否超过k就行。

T2(0/100):游戏

problem

题意:给你一个序列,让你先从序列中按顺序取出1个或2个数,接着另一个人(只有你俩)可以按顺序取出和上一个人取的个数相同或者多一个的数。直到取不动为止,剩下的数全部舍弃。最后比较双方取得的数的总和。如果双方都按最优策略来进行游戏,问你的总和最多能比别人多多少。

据凯爷说是根据11号考试改的原题。。。
样例

  • 输入
    1
    3
    1 3 2

  • 输出
    4

solution

然而当时完全忘了11号学的决策Dp了。。。(明明当时你就没懂
决策Dp套路:

状态转移方程(本题):

F【所有已经取走的数的个数】【上一个人取走的数的个数】= 正在取数的人的数的总和能比之前的人的最多多多少。

状态转移方程(老题):

F【i】= 在还剩下最小的i个数的情况下,先手比后手多多少。

T3(50/100):星星

problem

题意
问你在一个无向无自环无重边图(题目夜空中的星星)中形如<|>(由四个点五条线段构成的”鳕鱼”(咸鱼?)图形)的图形有多少个(出题人的说法)。
  

额。。。为理解方便我还是把出题人的意图更好的展示出来吧。。

  
  
  
上图!
  
  
  
  
  
  
  

。。。
凯爷眼中的鳕鱼
  
  
  
。。没错题上的鱼就长这样。。。我还帮他画好看了点。
  
  
  

然后考完就被人恶搞成:
你一定不知道是我在恶搞啊哈哈哈

样例

  • 输入 
    2
    4 5
    1 2
    2 3
    3 4
    4 1
    1 3
    4 6
    1 2
    2 3
    3 4
    4 1
    1 3
    2 4

  • 输出
    1
    6

solution

50%是乱搞的暴力。。。
枚举每一条边,再记录两端点的共同节点(就是与这两点都直接相连的点)的个数,然后更新答案。
标准的N^2算法。(还好没打炸。)
100%有哈希的有对N^2算法进行优化的。这里放出来的是优化的。

感想

多回顾!多练Dp!!多练模板!!!

代码:

T1:

my/std.cpp

#include<iostream>
#include<iomanip>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<string>
#include<algorithm>
#include<cmath>
#include<queue>
#include<vector>
using namespace std;

inline int read()
{
    int X=0,w=1; char ch=0;
    while(ch<'0' || ch>'9') {if(ch=='-') w=-1;ch=getchar();}
    while(ch>='0' && ch<='9') X=(X<<3)+(X<<1)+ch-'0',ch=getchar();
    return X*w;
}

int t,n,k,a[100005];

int main()
{
    t=read();
    while(t--)
    {
        n=read();k=read();memset(a,0,sizeof(a));
        for(int i=1;i<=n;i++)a[i]=read();
        sort(a+1,a+n+1);int cnt=n;
        while(a[cnt]-a[cnt-1]<=k&&cnt>1)cnt--;
        cout<<n-cnt+1<<endl;
    }
    return 0;
}

T2

std.cpp

#include<iostream>
#include<iomanip>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<string>
#include<algorithm>
#include<cmath>
#include<queue>
#include<vector>
using namespace std;

inline int read()
{
    int X=0,w=1; char ch=0;
    while(ch<'0' || ch>'9') {if(ch=='-') w=-1;ch=getchar();}
    while(ch>='0' && ch<='9') X=(X<<3)+(X<<1)+ch-'0',ch=getchar();
    return X*w;
}

int t,n,k,ans=0;
int a,sum[20005];
int f[20005][300];
int minuinf=-99999999;

int dfs(int x,int y)
{
    if(f[x][y]!=-1)return f[x][y];
    int ans=minuinf;
    if(x+y>n)return 0;
    if(x+y<=n)ans = max(ans,sum[x+y]-sum[x]-dfs(x+y,y));
    if(x+y+1<=n)ans = max(ans,sum[x+y+1]-sum[x]-dfs(x+y+1,y+1));
    f[x][y]=ans;
    return ans;
}

int main()
{
    t=read();
    while(t--)
    {
        n=read();ans=0;
        memset(f,0,sizeof(f));
        for(int i=1;i<=n;i++)a=read(),sum[i]=sum[i-1]+a;
        memset(f,-1,sizeof(f));
        ans = dfs(0,1);
        cout<<ans<<endl;
    }
    return 0;
}

T3

my.cpp

#include<iostream>
#include<iomanip>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<string>
#include<algorithm>
#include<cmath>
#include<queue>
#include<vector>
using namespace std;

inline int read()
{
    int X=0,w=1; char ch=0;
    while(ch<'0' || ch>'9') {if(ch=='-') w=-1;ch=getchar();}
    while(ch>='0' && ch<='9') X=(X<<3)+(X<<1)+ch-'0',ch=getchar();
    return X*w;
}

const int kkk=100800;

int t,n,m,u,v;
int first[kkk],cnt=0;
struct node{int u,v,next,num;}side[kkk*2];
void add(int u,int v)
{
    side[++cnt].u=u;
    side[cnt].v=v;
    side[cnt].num=0;
    side[cnt].next=first[u];
    first[u]=cnt;
}

long long ans=0;
bool visite[kkk];

int main()
{
    t=read();
    while(t--)
    {
        ans=0;cnt=0;
        memset(side,0,sizeof(side));                
        memset(first,0,sizeof(first));      

        n=read();m=read();
        for(int i=1;i<=m;i++)
        {
            u=read();v=read();
            add(u,v);add(v,u);
        }

        for(register int i=1;i<=cnt;i+=2)
        {
            int num=0;memset(visite,0,sizeof(visite));
            u=side[i].u;
            v=side[i].v;
            for(register int ii=first[u];ii;ii=side[ii].next)
            if(ii!=i)visite[side[ii].v]=true;
            for(register int ii=first[v];ii;ii=side[ii].next)
            if(visite[side[ii].v]==true)num++;
            ans += 1ll*(num*(num-1))/2;
        }
        cout<<ans<<endl;
    }
    return 0;
}

std.cpp

#include<iostream>
#include<iomanip>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<string>
#include<algorithm>
#include<cmath>
#include<queue>
#include<vector>
using namespace std;

inline int read()
{
    int X=0,w=1; char ch=0;
    while(ch<'0' || ch>'9') {if(ch=='-') w=-1;ch=getchar();}
    while(ch>='0' && ch<='9') X=(X<<3)+(X<<1)+ch-'0',ch=getchar();
    return X*w;
}

const int kkk=1e5+50;
#define iut register int

struct node{int u,v;}xside[kkk*2];
vector<int>side[kkk];
vector<int>que[kkk];
int n,m,mark,t;
int vis[kkk],deg[kkk],stk[kkk],pos[kkk];

inline bool comp(const int &a,const int &b){return deg[a]<deg[b];}

int main()
{
    //freopen("star.in","r",stdin);
    //freopen("star.out","w",stdout);
    t=read();
    while(t--)
    {
        n=read(),m=read();
        for(int i=1;i<=n;i++)side[i].clear(),stk[i]=i,deg[i]=0,que[i].clear();
        for(int i=1;i<=m;i++)
        {
            iut u=read(),v=read();
            xside[i].u=u,xside[i].v=v;
            side[u].push_back(v);
            side[v].push_back(u);
            ++deg[u];++deg[v];
        }
        sort(stk+1,stk+n+1,comp);
        for(int i=1;i<=n;i++)pos[stk[i]]=i;
        for(int i=1;i<=m;i++)
        {
            int u=xside[i].u,v=xside[i].v;
            if(pos[u]>pos[v])que[u].push_back(v);
            else que[v].push_back(u);
        }
        long long ans=0;
        for(int p=n;p>=1;p--)
        {
            ++mark;
            iut u=stk[p],v;
            for(iut i=side[u].size()-1;i>=0;i--)vis[side[u][i]]=mark;
            for(iut i=que[u].size()-1;i>=0;i--)
            {
                v=que[u][i];iut cnt=0;
                for(iut j=side[v].size()-1;j>=0;j--)if(vis[side[v][j]]==mark)++cnt;
                ans+=1ll*(cnt)*(cnt-1)/2;
            }
        }
        cout<<ans<<endl;
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值