A.一个n,m的监狱,每个格子都有人,一个时间每人都可往以上下左右移动一格,允许一个格子多个人,问所有人都到(r,c)需要的时间是多少?
x,y坐标分开考虑x最远是abs(x-r)与abs(r-1)的最大值y坐标最远是abs(y-c)与abs(c-1)的最大值,二者都取最大即可得到花费时间最长的坐标点
#include<bits/stdc++.h>
using namespace std;
int main()
{
int t;
cin >> t;
while(t--)
{
int n, m, r, c;
cin >> n >> m >> r >> c;
int x1 = abs(n-r);
int y1 = abs(m-c);
int x2 = abs(1-r);
int y2 = abs(1-c);
cout << max(x1,x2) + max(y1,y2) << endl;
}
}B.
1-n的房子,每个房子都有自己的颜色,为了让所有房子变成一个颜色,你每次可以选取一个长度不超过k的区间[l,r]然后对这个区间的每个房子都粉刷成任意颜色。问最少的次数。
颜色种类数据不超过100,暴力枚举即可。每次遇到颜色不一样的就粉刷一个长度为k的区间就行。
#include<bits/stdc++.h>
using namespace std;
#define N 100005
int c[N];
int main()
{
ios::sync_with_stdio(false); cin.tie(0);
int t;
cin >> t;
while(t--){
int n, k;
cin >> n >> k;
for(int i=1; i<=n; i++)
cin >> c[i];
int ans = 1e9;
for(int i=1; i<=100; i++){
int s = 0;
for(int j=1; j<=n; j++){
if(c[j] != i) s++, j+=k-1;
}
ans = min(ans, s);
}
cout << ans << endl;
}
}C.
你在设计一个游戏,有n个格子,1代表格子上一开始有平台,0代表没有,游戏会给你一个小球,小球一开始弹到序号为p的然后接着往后弹到p+k...,小球只能打到有平台的格子,为了让小球能够到达或超过终点,你花时间x在格子设置平台,或是花时间y删除第一个格子(序号将重新标记)。问最少花费多少时间
看错题了,原来是删第一个格子...
那么dp[i]表示经过i到最后的花费,在所有dp[i]+y*(i-p)中取个最小就行了。有点后缀和的意思。
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
char a[100005];
ll dp[100005];
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
int n, p, k, x, y;
memset(dp, 0, sizeof(dp));
ll ans = 1e18;
scanf("%d%d%d",&n,&p,&k);
scanf("%s", a+1);
scanf("%d%d",&x,&y);
for(int i=n; i>=p; i--){
dp[i] = x*(1-a[i]+'0');
if(i+k <= n)
dp[i] += dp[i+k];
ans = min(ans, dp[i]+(i-p)*y);
}
printf("%lld\n",ans);
}
}D.现在有一个非递减的数列,你可以把其中连续的两个数字异或,并用异或的值代替这两个数字原来位置,数列长度会减少1,问最少多少次可以将这个数列打破非递减规则。
构造发现如果有连续3个的最高位1位置一样,总可以1次达成目的。那么只需要考虑同一最高位至多出现2次的情况,那么在最大值1e9的情况下,当序列中数字不冲突的时候,至多有60个数字,那么题目就被剪枝到60以下了。
考虑两种情况:一种情况是一个区间直接异或起来。
还有一种情况是两个区间分别异或再合并起来的情况。
#include<bits/stdc++.h>
using namespace std;
#define int long long
#define debug(x) cout << #x << ":" << x <<endl;
#define N 200005
int a[N], b[N];
signed main()
{
int n;
cin >> n;
for(int i=1; i<=n; i++){
cin >> a[i];
b[i] = b[i-1]^a[i];
}
if(n>60){
cout << 1 << endl; return 0;
}
int ans = 1e18;
for(int l=1; l<n; l++){
for(int i=1; i+l-1<=n; i++){
int tmp = b[i+l-1]^b[i-1];
if(tmp >= a[i-1])
{
if(i+l-1 == n || tmp <= a[i+l])
continue;
}
ans = min(ans, l-1);
}
}
for(int l=1; l<=n-1; l++){
for(int i=1; i+l-1 <= n; i++){
for(int j=i+l; j<=n; j++){
int t1 = b[i+l-1]^b[i-1];
int t2 = b[j]^b[i+l-1];
if(t1 <= t2) continue;
ans = min(ans, l-1+j-i-l);
}
}
}
if(ans == 1e18)
cout << -1 << endl;
else
cout << ans << endl;
}
京公网安备 11010502036488号