Codeforces Round 967 (Div. 2) 8.20

8.20 Div 2

Dashboard - Codeforces Round 967 (Div. 2) - Codeforces

A. Make All Equal

思路

题目中说相邻元素比大小,再删除,最后只剩相同元素。求最少运算次数。

找几个数字模拟一下就发现,凡是不同的总有办法删去,所以答案就是 n − ( 最多相同元素个数 ) n-(最多相同元素个数) n(最多相同元素个数)

代码

int a[N];
void solve()
{
    int n,h=1,ans=1;
    cin>>n;
    fir(i,1,n)
    cin>>a[i];
    sort(a,a+n+1);
    fir(i,2,n)
    {
        if(a[i]==a[i-1])
        h++;
        else
        {
            ans=max(ans,h);
            h=1;
        }
    }
    ans=max(ans,h);
    cout<<n-ans<<'\n';
}
signed main()
{
    IOS
    int t;
    cin>>t;
    while(t--)
    solve();
    return 0;
}

B. Generate Permutation

首尾两台打字机,分别可以进行

回车

写入

移动指针

求用两台打字机回车次数相同的数字序列

思路

发现,偶数永远不行

奇数

正序输出 [ 1 , n / 2 ] [1,n/2] [1,n/2],倒序输出 [ n , n / 2 + 1 ] [n , n/2+1] [n,n/2+1]

这样回车次数全为 n / 2 + 1 n/2+1 n/2+1.

代码

void solve()
{
    int n;
    cin>>n;
    if(n%2==0)
    cout<<"-1"<<'\n';
    else
    {
        fir(i,1,n/2)
        cout<<i<<" ";
        for(int i=n;i>n/2;i--)
        cout<<i<<" ";
        cout<<'\n';
    }
}

C. Guess The Tree

这是一道交互题

  • “? a b” - Misuki 会告诉你哪个节点 x 最小化了 |d(a,x)−d(b,x)| ,其中 d(x,y) 节点 x 和 y 之间的距离。如果存在不止一个这样的节点,那么 Misuki 会告诉您哪个节点能使 d(a,x) 最小化。

  • 输出一行格式为"! a1 b1 a2 b2 … an−1 bn−1 " (不带引号),这意味着每个 1≤i≤n−1 节点的 ai和 bi之间都有一条边。您可以按任意顺序打印这些边。

思路

不断判断两个点x,b,如果输入a的是两点之一,说明二者之间有边,存起来,否则再询问a,b.类似于二分查找得出与b相连的边。

关键是x,b如何选取

我最初是相邻的两个进行判断,但出现了问题,有些边无法发现,后来改一下,样例1过了,边没漏,为什么也不太清楚,又出现问题超出测试 2 的空闲限制

如果全以1为x,作为基准。看从1到各个点的最小化节点,是谁,再不断二分查找。

这样看起来就比较严谨。是因为这样:

不用担心想我之前一样会重复选择同一边,导致漏选

从1到x判断,最终找到ax所连边。

我们是从前往后找与某节点相连的边。如果(a>x),不需要担心一会遍历到a会选择(xa)。因为都是从1开始判断,刚才结果是a,说明a比x距离1更近,就肯定不会考虑x。

代码

#define PII pair<int,int> 
#define fi first
#define se second
map<PII,int> mp; 
void solve()
{
    mp.clear();
    int n;
    cin>>n;
    fir(i,2,n)
    {
        int x=1,b=i;
        while(x!=b)
        {
            cout<<"? "<<x<<" "<<b<<'\n';
            int a;cin>>a;
            if(a==x||a==b) break;
            x=a;
        }
        mp[{x,b}]=1;
    }
    cout<<"! ";
    for(auto it:mp)
    {
        cout<<it.fi.fi<<" "<<it.fi.se<<" ";
    }
    cout.flush();
}
signed main()
{ 
    int t;
    cin>>t;
    while(t--) {     solve();
    }
    return 0;
}

总结

这次题目看似复杂,混淆罢了。但是严谨一点,多模拟试几个,也不多。就是慢了点,需要更敏锐发现,快速模拟。第三题交互,之前做过类似,不该在15n,-1处纠结。还是要看样例,从中发现合理正确的询问方式。题意关于d[ax]最小化,又糊涂了。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值