H. Hardcore Hangman

题意:交互题,你要每次询问一个字符串,然后会反馈给你 n个数字,每个数字代表,在x这个位置上,是你的字符串中的给字符之一,最多七次访问,如何才能得出答案

思路:与小鼠试毒类似,使用二进制来表示状态,00000五位,首先我们对a到z这个字符串进行询问,得出答案的长度,然后我们对第一位是1的字符进行询问,得到一些答案,对于每一位来说,比如abc,访问a,c等等等,会得到1和3,那么我们对第三位和第一位的二进制的第一位中把1补上,然后询问b,c,得到2,3,然后把2,3上的二进制第二位补上1,然后就得到了a,b,c,即可

diamond:

#include<bits/stdc++.h>
using namespace std;
//#define int long long
void solve() {
    int n;
    cout<<"? ";
    for (int i = 0; i <26 ; ++i) {
        cout<<(char)('a'+i);
    }
    cout<<endl;
    cin>>n;
    vector<int>ans((int)n+1);
    for (int i = 0; i <n ; ++i) {
        int x;
        cin>>x;
    }
    for (int i = 0; i <5 ; ++i) {
        cout<<"? ";
        for (int j = 0; j <26 ; ++j) {
            if(j&(1<<i))cout<<(char)('a'+j);
        }
        int t;
        cout<<endl;
        cin>>t;
        for (int j = 0; j <t ; ++j) {
            int x;
            cin>>x;
            ans[x]|=(1<<i);
        }
    }
    cout<<"! ";
    for (int i = 1; i <=n ; ++i) {
        cout<<(char)('a'+ans[i]);
    }
    cout<<endl;
}
signed main(){
    ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
    int t=1;
//    cin>>t;
    while (t--){
        solve();
    }
}

D. Diabolic Doofenshmirtz

题意: 交互题,你的目的是得到一个答案x,你询问? y,会反馈给你一个y%x,你最多42次询问就必须猜出答案

思路:直接倍增的询问,比如x=19,询问,1,2,4,8,16,32,当32时, 你会得到13,那么你就可以得到答案32-13=19

diamond:

#include<bits/stdc++.h>
using namespace std;
#define int long long
signed main(){
ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
    int mid=1;
    while (1){
        cout<<"? "<<mid<<endl;
        int x;
        cin>>x;
        if(x<mid){
            cout<<"! "<<mid-x<<endl;
            return 0;
        }
        mid=mid<<1;
    }
}

A. Alternative Architecture

题意:给一个长为a,宽为b的矩形,将矩形旋转形成一个方向,问满足可以钉在积木方格上的有几个方向

思路:方向转动之后,会形成三角形,首先是斜边是矩形的长或宽,然后就是看两个直角边是否都是整数即可,根据相似得到$(b*i)%a==0&&(b*res)%a==0$,则就可以得到答案,由于可以将矩形沿着宽翻过来,则又形成一种,所以 * 2,如果长等于宽,就重复了,不用乘

diamond:

#include<bits/stdc++.h>
using namespace std;
#define int long long
void solve() {
    int a,b;
    cin>>a>>b;
    a--,b--;
    int ans=1;
//    int gcd=__gcd(a,b);
    if(a>b)swap(a,b);
//    a/=gcd;
//    b/=gcd;
    for (int i = 1; i <=a-1 ; ++i) {
        int s=a*a-i*i;
        int res= ::sqrt(s);
        if(res*res==s){
             if((b*i)%a==0&&(b*res)%a==0){
                 ans++;
             }
        }
    }
    if(a!=b)ans*=2;
    cout<<ans<<endl;

}
signed main(){
    ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
    int t=1;
//    cin>>t;
    while (t--){
        solve();
    }
}

L. Lots of Land

题意:给一个 x * y的矩阵,问你能否将n个字母填入j矩阵,使得每个字符个数都相等,且每一块字符都占据一个矩形

思路:我们可以这样想,每个字母我们都分成相同的矩形,这样就要求n的因子,首先n可以由哪些数相乘得到,然后这些边还要分别被x,y整除,才行,那么我们就找到一个满足条件的,然后填入矩阵即可

diamond:

#include "bits/stdc++.h"
using namespace std;
char g[105][105];
signed main() {
    int x, y, n;
    cin >> x >> y >> n;
    int vis = 0;
    if (x > y) {
        swap(x, y);
        vis = 1;
    }
    vector<pair<int, int>> st;
    for (int i = 1; i <= n / i; i++)
        if (n % i == 0) st.push_back({i, n / i});
//    for (auto i : st) {
//        cout << i.first << " " << i.second << endl;
//    }
//
    int a, b;
    int stt=0;
    for (auto i: st) {

        if (x % i.first == 0&&y%i.second==0) {
            a = x / i.first;
            b= y/i.second;
            stt=1;
            break;
        }
        if (x % i.second == 0&&y%i.first==0) {
            a = x / i.second;
            b= y/i.first;
            stt=1;
            break;
        }
    }
    if (stt == 0) {
        cout << "IMPOSSIBLE";
        return 0;
    }
//    cout<<a<<' '<<b<<endl;
    char ans = 'A';
    for (int j = 1; j <= x; ++j) {
        for (int k = 1; k <= y; ++k) {
            if (g[j][k] == 0) {
                for (int l = j; l < j + a; ++l) {
                    for (int m = k; m < k + b; ++m) {
                        g[l][m] = ans;
                    }
                }
                ans++;
            }
        }
    }
    if (vis == 0)
        for (int i = 1; i <= x; ++i) {
            for (int j = 1; j <= y; ++j) {
                cout << g[i][j];
            }
            cout << endl;
        }
    else {
        for (int i = 1; i <= y; ++i) {
            for (int j = 1; j <= x; ++j) {
                cout << g[j][i];
            }
            cout << endl;
        }
    }
}

I. Improving IT

题意:你必须每天都要有CPU,且你的CPU要在m天后必须换,也可以提前更换,然后给你每天的那个购买的CPU的价格,以及后续几天出售所能卖多少钱,你在第n+1天必须把CPU卖掉,问你在第n+1天时,最少花了多少钱, 也可以是负数,就是反而盈利了

思路:假设我们今天买今天的CPU,那么我们可以推出你在后续m天卖CPU的价格,我们可以记录状态,然后每遍历到一天,就更新截止到后几天的某一天的最小花费,然后答案就是$f[n+1]$

diamond:

#include "bits/stdc++.h"
using namespace std;
#define int long long
signed main() {
    int n, m;
    cin >> n >> m;
    vector<int> a(n + 1 + 1+2, 0);
    vector<int> b[n + 1+2];
//1    vector<vector<int>> f(n + 1, vector<int>(m + 1,1e18));
    vector<int> f(n + 1 + 1+2, 1e18);

    for (int i = 1; i <= n; i++) {
        cin >> a[i];
        for (int j = 1; j <= min(m, n - i + 1); ++j) {
            int x;
            cin >> x;
            b[i].push_back(x);
        }
    }
    f[1] = a[1];
    for (int i = 1; i <= n; ++i)
        for (int j = 0; j < b[i].size(); ++j) {
            f[i + j + 1] = min(f[i + j + 1], f[i] - b[i][j] + a[i + j + 1]);
        }
//    for (int i = 1; i <=n+1 ; ++i) {
//        cout<<i<<' '<<f[i]<<endl;
//    }
//    cout<<endl;
    cout <<f[n+1];
}

 
posted on 2023-09-13 21:24  IR101  阅读(11)  评论(0编辑  收藏  举报  来源