contents:
A. Linear Keyboard
You are given a keyboard that consists of 26 keys. The keys are arranged sequentially in one row in a certain order. Each key corresponds to a unique lowercase Latin letter.
You have to type the word s on this keyboard. It also consists only of lowercase Latin letters.
To type a word, you need to type all its letters consecutively one by one. To type each letter you must position your hand exactly over the corresponding key and press it.
Moving the hand between the keys takes time which is equal to the absolute value of the difference between positions of these keys (the keys are numbered from left to right). No time is spent on pressing the keys and on placing your hand over the first letter of the word.
For example, consider a keyboard where the letters from ‘a’ to ‘z’ are arranged in consecutive alphabetical order. The letters ‘h’, ‘e’, ‘l’ and ‘o’ then are on the positions 8, 5, 12 and 15, respectively. Therefore, it will take |5−8|+|12−5|+|12−12|+|15−12|=13 units of time to type the word “hello”.
Determine how long it will take to print the word s.
思路
ypAC
#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define db double
#define pii pair<int, int>
#define psi pair<string, int>
#define ull unsigned ll
#define pb push_back
#define mp make_pair
#define X first
#define Y second
#define ld long double
const int N = 1E5 + 7;
#define INF ~0ULL
int t;
string s1;
string s2;
int main()
{
cin >> t;
while (t--)
{
cin >> s1;
cin >> s2;
int a[150];
for (int i = 0; i <= 25; i++)
{
a[s1[i]] = i;
}
int len = s2.length();
ll ans = 0;
for (int i = 1; i < len; i++)
{
ans += abs(a[s2[i]] - a[s2[i - 1]]);
}
cout<<ans<<endl;
}
}
dalaoAC
#include<bits/stdc++.h>
using namespace std;
int main(){
int t;
cin>>t;
while(t--){
string s1,s2;
cin>>s1>>s2;
int p[300];
for(int i=0;i<26;i++){
p[s1[i]]=i;
}
int ans=0;
for(int i=1;i<s2.length();i++){
ans+=abs(p[s2[i]]-p[s2[i-1]]);
}
cout<<ans<<endl;
}
}
B. Odd Grasshopper
The grasshopper is located on the numeric axis at the point with coordinate x0.
Having nothing else to do he starts jumping between integer points on the axis. Making a jump from a point with coordinate x with a distance d to the left moves the grasshopper to a point with a coordinate x−d, while jumping to the right moves him to a point with a coordinate x+d.
The grasshopper is very fond of positive integers, so for each integer i starting with 1 the following holds: exactly i minutes after the start he makes a jump with a distance of exactly i. So, in the first minutes he jumps by 1, then by 2, and so on.
The direction of a jump is determined as follows: if the point where the grasshopper was before the jump has an even coordinate, the grasshopper jumps to the left, otherwise he jumps to the right.
For example, if after 18 consecutive jumps he arrives at the point with a coordinate 7, he will jump by a distance of 19 to the right, since 7 is an odd number, and will end up at a point 7+19=26. Since 26 is an even number, the next jump the grasshopper will make to the left by a distance of 20, and it will move him to the point 26−20=6.
Find exactly which point the grasshopper will be at after exactly n jumps.
思路
打表找规律
x0为奇数是 n的符号循环节是 + - - +
x0为偶数是 n的符号循环节是 - + + -
对4取模之后计算剩余量
ypAC
#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define db double
#define pii pair<int, int>
#define psi pair<string, int>
#define ull unsigned ll
#define pb push_back
#define mp make_pair
#define X first
#define Y second
#define ld long double
const int N = 1E5 + 7;
#define INF ~0ULL
int t;
ll a, b;
int main()
{
cin >> t;
while (t--)
{
cin >> a >> b;
ll ans = a;
int len = b % 4;
a = abs(a);
if (a % 2 == 1)
{ // jishu
if (len == 0)
{
cout << ans << endl;
}
else if (len == 1)
{
ans += b;
cout << ans << endl;
}
else if (len == 2)
{
ans += b - 1;
ans -= b;
cout << ans << endl;
}
else
{
ans += b - 2;
ans -= b - 1;
ans -= b;
cout << ans << endl;
}
}
else
{
if (len == 0)
{
cout << ans << endl;
}
else if (len == 1)
{
ans -= b;
cout << ans << endl;
}
else if (len == 2)
{
ans -= b - 1;
ans += b;
cout << ans << endl;
}
else
{
ans -= b - 2;
ans += b - 1;
ans += b;
cout << ans << endl;
}
}
}
}
dalaoAC
#include<bits/stdc++.h>
using namespace std;
int main(){
int t;
cin>>t;
while(t--){
long long a,b;
cin>>a>>b;
for(long long i=b/4*4+1;i<=b;i++){
if(a%2){
a+=i;
}
else a-=i;
}
cout<<a<<endl;
}
}
C. Minimum Extraction
Yelisey has an array a of n integers.
If a has length strictly greater than 1, then Yelisei can apply an operation called minimum extraction to it:
First, Yelisei finds the minimal number m in the array. If there are several identical minima, Yelisey can choose any of them.
Then the selected minimal element is removed from the array. After that, m is subtracted from each remaining element.
Thus, after each operation, the length of the array is reduced by 1.
For example, if a=[1,6,−4,−2,−4], then the minimum element in it is a3=−4, which means that after this operation the array will be equal to a=[1−(−4),6−(−4),−2−(−4),−4−(−4)]=[5,10,2,0].
Since Yelisey likes big numbers, he wants the numbers in the array a to be as big as possible.
Formally speaking, he wants to make the minimum of the numbers in array a to be maximal possible (i.e. he want to maximize a minimum). To do this, Yelisey can apply the minimum extraction operation to the array as many times as he wants (possibly, zero). Note that the operation cannot be applied to an array of length 1.
Help him find what maximal value can the minimal element of the array have after applying several (possibly, zero) minimum extraction operations to the array.
思路
群体演变
sort 之后 ,最大差值
ypAC
#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define db double
#define pii pair<int, int>
#define psi pair<string, int>
#define ull unsigned ll
#define pb push_back
#define mp make_pair
#define X first
#define Y second
#define ld long double
const int N = 2E5 + 7;
#define INF ~0ULL
int t;
int n;
ll arr[N];
ll now;
int main()
{
cin >> t;
while (t--)
{
cin >> n;
for (int i = 1; i <= n; i++)
{
cin >> arr[i];
}
sort(arr+1,arr+1+n);
ll mi = arr[1];
for (int i = 2; i <= n; i++)
{
ll x = arr[i] - arr[i - 1];
mi = max(mi,x);
}
cout<<mi<<endl;
}
}
dalaoAC
#include<bits/stdc++.h>
using namespace std;
int main(){
int t;
cin>>t;
while(t--){
int n;
cin>>n;
long long a[n+5];
for(int i=1;i<=n;i++)cin>>a[i];
sort(a+1,a+n+1);
long long tmp=0,ans=a[1];
for(int i=1;i<n;i++){
tmp=-a[i];
ans=max(ans,a[i+1]+tmp);
}
cout<<ans<<endl;
}
}
D. Blue-Red Permutation
You are given an array of integers a of length n. The elements of the array can be either different or the same.
Each element of the array is colored either blue or red. There are no unpainted elements in the array. One of the two operations described below can be applied to an array in a single step:
either you can select any blue element and decrease its value by 1;
or you can select any red element and increase its value by 1.
Situations in which there are no elements of some color at all are also possible. For example, if the whole array is colored blue or red, one of the operations becomes unavailable.
Determine whether it is possible to make 0 or more steps such that the resulting array is a permutation of numbers from 1 to n?
In other words, check whether there exists a sequence of steps (possibly empty) such that after applying it, the array a contains in some order all numbers from 1 to n (inclusive), each exactly once.
思路
蓝色可减少红色可增
sort
左蓝右红
当最小的蓝色比当前位置小,说明减少不了,次数无处安放
红色亦然
ypAC
#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define db double
#define pii pair<int, int>
#define psi pair<string, int>
#define ull unsigned ll
#define pb push_back
#define mp make_pair
#define X first
#define Y second
#define ld long double
const int N = 2E5 + 7;
#define INF ~0ULL
inline int read()
{
int x = 0;
char c = getchar();
while (c < '0' || c > '9')
c = getchar();
while (c >= '0' && c <= '9')
{
x = x * 10 + c - '0';
c = getchar();
}
return x;
}
int t;
int n;
int arr[N];
char s[N];
vector<int> red;
vector<int> bll;
int main()
{
cin >> t;
while (t--)
{
cin >> n;
red.clear();
bll.clear();
for (int i = 1; i <= n; i++)
{
cin >> arr[i];
}
scanf("%s", s + 1);
for (int i = 1; i <= n; i++)
{
if (s[i] == 'B')
{
bll.push_back(arr[i]);
}
else
{
red.push_back(arr[i]);
}
}
sort(red.begin(), red.end());
sort(bll.begin(), bll.end());
int lena = bll.size();
int lenb = red.size();
bool f1 = 1;
bool f2 = 1;
for (int i = 1; i <= lena; i++)
{
if (bll[i-1] < i)
{
f1 = 0;
break;
}
}
for (int i = lena + 1; i <= n; i++)
{
if (red[i-lena-1] > i)
{
f2 = 0;
break;
}
}
if(f1==0||f2==0){
cout<<"NO"<<endl;
}
else{
cout<<"YES"<<endl;
}
}
}
dalaoAC
#include<bits/stdc++.h>
using namespace std;
int main(){
int t;
cin>>t;
while(t--){
int n;
cin>>n;
int a[n+5];
for(int i=1;i<=n;i++){
cin>>a[i];
}
string s;
vector<int>p1,p2;
cin>>s;
for(int i=0;i<n;i++){
if(s[i]=='B'){
p1.push_back(a[i+1]);
}
else{
p2.push_back(a[i+1]);
}
}
sort(p1.begin(),p1.end());
sort(p2.begin(),p2.end(),greater<int>());
int ok=1;
for(int i=0;i<p1.size();i++){
if(p1[i]<=i){
ok=0;
break;
}
}
for(int i=0;i<p2.size();i++){
// cerr<<p2[i]<<' ';
if(p2[i]>n-i){
ok=0;
break;
}
}
// cerr<<endl;
if(ok){
cout<<"Yes"<<endl;
}
else cout<<"No"<<endl;
}
}
E. Robot on the Board 1
The robot is located on a checkered rectangular board of size n×m (n rows, m columns). The rows in the board are numbered from 1 to n from top to bottom, and the columns — from 1 to m from left to right.
The robot is able to move from the current cell to one of the four cells adjacent by side.
The sequence of commands s executed by the robot is given. Each command is denoted by one of the symbols ‘L’, ‘R’, ‘D’ or ‘U’, and triggers the movement to left, right, down or up, respectively.
The robot can start its movement in any cell. The robot executes the commands starting from the first one, strictly in the order in which they are listed in s. If the robot moves beyond the edge of the board, it falls and breaks. A command that causes the robot to break is not considered successfully executed.
The robot’s task is to execute as many commands as possible without falling off the board. For example, on board 3×3, if the robot starts a sequence of actions s=“RRDLUU” (“right”, “right”, “down”, “left”, “up”, “up”) from the central cell, the robot will perform one command, then the next command will force him to cross the edge. If the robot starts moving from the cell (2,1) (second row, first column) then all commands will be executed successfully and the robot will stop at the cell (1,2) (first row, second column).
思路
相对唯一
假设1,1
对无限大的坐标免疫
对于超出1,1比如-1,-1
就要相对唯一
还是模拟
ypAC
#include <bits/stdc++.h>
using namespace std;
const int N = 1e6 + 7;
char s[N];
int t, n, m;
int l, r, u, d;//边界
int x, y, stx, sty, len;
int main()
{
cin >> t;
while (t--)
{
scanf("%d%d%s", &n, &m, s + 1);
l = r = u = d = x = y = 0;
stx = sty = 1;
len = strlen(s + 1);
for (int i = 1; i <= len; i++)
{
if (s[i] == 'L')
y--;
if (s[i] == 'R')
y++;
if (s[i] == 'U')
x--;
if (s[i] == 'D')
x++;
u = min(u, x), d = max(d, x);
l = min(l, y), r = max(r, y);
if(d-u+1>n||r-l+1>m) break;
stx = 1-u,sty = 1-l;
}
cout<<stx<<" "<<sty<<endl;
}
return 0;
}
大佬AC
#include<bits/stdc++.h>
using namespace std;
int main(){
int t;
cin>>t;
while(t--){
int n,m;
cin>>n>>m;
string s;
cin>>s;
int l=0,r=0,u=0,d=0,ok=0,cx=0,cy=0;
for(int i=0;i<s.length();i++){
if(s[i]=='R'){
cy++;
r=max(r,cy);
if(l+r>=m or u+d>=n){
r--;
break;
}
}
if(s[i]=='L'){
cy--;
l=max(l,-cy);
if(l+r>=m or u+d>=n){
l--;
break;
}
}
if(s[i]=='U'){
cx--;
u=max(u,-cx);
if(l+r>=m or u+d>=n){
u--;
break;
}
}
if(s[i]=='D'){
cx++;
d=max(d,cx);
if(l+r>=m or u+d>=n){
d--;
break;
}
}
}
cout<<u+1<<' '<<l+1<<endl;
}
}
F. Robot on the Board 2
dalaoAC
#include<bits/stdc++.h>
using namespace std;
int n, m;
char s[2001][2001];
int v[2000][2000], vdx;
int c[2000][2000];
void next(int& x, int& y) {
if (s[x][y] == 'U') x--;
else if (s[x][y] == 'D') x++;
else if (s[x][y] == 'L') y--;
else if (s[x][y] == 'R') y++;
}
void cycle(int x, int y) {
if (x < 0 || x >= n || y < 0 || y >= m || c[x][y])
return;
if (v[x][y] == vdx) {
int count = 0;
for (int i = x, j = y;;) {
next(i, j), count++;
if (i == x && j == y) break;
}
for (int i = x, j = y;;) {
next(i, j), c[i][j] = count;
if (i == x && j == y) break;
}
} else if (v[x][y] == 0){
v[x][y] = vdx;
next(x, y);
cycle(x, y);
}
}
int dfs(int x, int y) {
if (x < 0 || x >= n || y < 0 || y >= m) return 0;
if (c[x][y]) return c[x][y];
int nx = x, ny = y;
next(nx, ny);
return c[x][y] = dfs(nx, ny) + 1;
}
void solve() {
for (int i = 0; i < n; ++i)
for (int j = 0; j < m; ++j)
v[i][j] = c[i][j] = 0;
for (int i = 0; i < n; ++i)
for (int j = 0; j < m; ++j)
if (v[i][j] == 0) {
++vdx; cycle(i, j);
}
++vdx;
for (int i = 0; i < n; ++i)
for (int j = 0; j < m; ++j)
if (!c[i][j])
dfs(i, j);
int x = 0, y = 0;
for (int i = 0; i < n; ++i)
for (int j = 0; j < m; ++j)
if (c[x][y] < c[i][j])
x = i, y = j;
printf("%d %d %d\n", x + 1, y + 1, c[x][y]);
}
int main() {
int tc; scanf("%d", &tc);
while (tc--) {
scanf("%d%d", &n, &m);
for (int i = 0; i < n; ++i)
scanf("%s", s[i]);
solve();
}
}
G. Banquet Preparations 1
A known chef has prepared n dishes: the i-th dish consists of ai grams of fish and bi grams of meat.
The banquet organizers estimate the balance of n dishes as follows. The balance is equal to the absolute value of the difference between the total mass of fish and the total mass of meat.
Technically, the balance equals to ∣∣∣∑i=1nai−∑i=1nbi∣∣∣. The smaller the balance, the better.
In order to improve the balance, a taster was invited. He will eat exactly m grams of food from each dish. For each dish, the taster determines separately how much fish and how much meat he will eat. The only condition is that he should eat exactly m grams of each dish in total.
Determine how much of what type of food the taster should eat from each dish so that the value of the balance is as minimal as possible. If there are several correct answers, you may choose any of them.
dalaoAC
#include<bits/stdc++.h>
using namespace std;
using lint = long long;
int n, m, a[200000], b[200000];
int mn[200000], mna[200000], mnb[200000];
int mx[200000], mxa[200000], mxb[200000];
void solve() {
for (int i = 0; i < n; ++i) {
mna[i] = min(a[i], m);
mnb[i] = m - mna[i];
mn[i] = a[i] - mna[i] - (b[i] - mnb[i]);
mxb[i] = min(b[i], m);
mxa[i] = m - mxb[i];
mx[i] = a[i] - mxa[i] - (b[i] - mxb[i]);
}
lint low = 0;
for (int i = 0; i < n; ++i)
low += mn[i];
lint ret = low;
vector<pair<int, int>> ans;
for (int i = 0; i < n; ++i) {
if (ret >= 0) {
ans.emplace_back(mna[i], mnb[i]);
} else if (ret + mx[i] - mn[i] <= 0) {
ret += mx[i] - mn[i];
ans.emplace_back(mxa[i], mxb[i]);
} else {
int eat = abs(ret) / 2;
ret += eat * 2;
ans.emplace_back(mna[i] - eat, mnb[i] + eat);
}
}
printf("%lld\n", abs(ret));
for (auto [x, y] : ans)
printf("%d %d\n", x, y);
}
int main() {
int tc; scanf("%d", &tc);
while (tc--) {
scanf("%d%d", &n, &m);
for (int i = 0; i < n; ++i)
scanf("%d%d", a + i, b + i);
solve();
}
}
H. Banquet Preparations 2
The chef has cooked n dishes yet again: the i-th dish consists of ai grams of fish and bi grams of meat.
Banquet organizers consider two dishes i and j equal if ai=aj and bi=bj at the same time.
The banquet organizers estimate the variety of n dishes as follows. The variety of a set of dishes is equal to the number of different dishes in it. The less variety is, the better.
In order to reduce the variety, a taster was invited. He will eat exactly mi grams of food from each dish. For each dish, the taster determines separately how much fish and how much meat he will eat. The only condition is that he will eat exactly mi grams of the i-th dish in total.
Determine how much of what type of food the taster should eat from each dish so that the value of variety is the minimum possible. If there are several correct answers, you may output any of them.
dalaoAC
#include <bits/stdc++.h>
using namespace std;
#define mp make_pair
#define fr first
#define sc second
long long n,wg[200069],lz[200069],sq[200069];
pair<pair<long long,pair<long long,long long>>,long long> as[200069];
int main()
{
long long t,rr,i,k,l,w,mn,mx,pz,z=0;
scanf("%lld",&t);
for(rr=0;rr<t;rr++)
{
scanf("%lld",&n);
for(i=1;i<=n;i++)
{
scanf("%lld%lld%lld",&k,&l,&w);
mn=max(w-l,0ll);
mx=min(k,w);
wg[i]=w;
lz[i]=mn;
as[i]={{k+l-w,{k-mn,k-mx}},i};
}
sort(as+1,as+n+1);
z=0;
for(i=1;i<=n;i++)
{
w=as[i].fr.fr;
k=as[i].fr.sc.fr;
l=as[i].fr.sc.sc;
pz=as[i].sc;
if(i==1||w!=as[i-1].fr.fr||l>mx)
{
z++;
mx=k;
}
sq[pz]=lz[pz]+k-mx;
}
printf("%lld\n",z);
for(i=1;i<=n;i++)
{
printf("%lld %lld\n",sq[i],wg[i]-sq[i]);
}
}
}
本文解析了八个算法题目,包括键盘操作时间计算、蚱蜢跳跃位置预测、数组最小元素最大化、蓝红排列验证等,提供了详细的解题思路及代码实现。

581

被折叠的 条评论
为什么被折叠?



