题意:交互题,你要每次询问一个字符串,然后会反馈给你 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();
}
}
题意: 交互题,你的目的是得到一个答案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,宽为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();
}
}
题意:给一个 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;
}
}
}
题意:你必须每天都要有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];
}