CSP first simulation

Question A

Problem Description:

There is a pointer on a ring that initially points to the letter a. Gugudong can rotate clockwise or counterclockwise one frame at a time. For example, a rotates clockwise to z and counterclockwise to b. Gu Gudong has a string in his hand, but he is too stupid, so he came to ask for your help and asked how many times he had to turn at least.
Enter a line of string and output the minimum number of rotations.
The ring is shown below
a question diagram

Ideas

Enter a character string and save it with string, traverse each character in turn to calculate the number of times required to move from the reference character, that is, determine whether the movement is clockwise or counterclockwise. Here I use the calculation of the difference between two characters Judging from the size relationship with 13, if the number is greater than 13, the number of counterclockwise rotations will be less, otherwise, the clockwise rotation will be used, and then the reference character will be updated to calculate the next character until the end of the string.

Code


#include<bits/stdc++.h>
using namespace std;
  
string str;
int main()
{
 int count=0;
 cin>>str;
 char now='a';
  for(int i=0;i<str.size();i++)
  {
   if((str[i]-now+26)%26>13)
   {
    count+=(26-((str[i]-now+26)%26));
   }
   else count+=((str[i]-now+26)%26);
   now=str[i];
  }
 cout<<count<<endl;
 return 0;
 
}

to sum up

This question is not difficult, it can be easily solved by using modulo 26

Question B

Problem Description

Gugudong needs to buy ai raw fried every day. However, in order to stimulate consumption, there are only two ways to buy shengjian: ① buy two shengjian at a time on a certain day. ② Buy a raw fried today, and buy a raw fried for tomorrow, the store will give a voucher, the next day to use the voucher to get. There are no other purchase methods, these two purchase methods can be used countless times, but Gu Gudong is a frugal good boy, he left after training, not allowed to have a voucher at the end of training. Gu Gu Dong is very rich, you don't need to worry about Gu Gu Dong being rich, but Gu Gu Dong is too stupid, he wants to ask you if he can just buy ai shengjian every day during the exam week.
Enter the number of days of the exam week n (1 <= n <= 100000), and the number of raw fried to buy a day n days ai (0 <= ai <= 10000).

Ideas

Here you can use a simple simulation, according to the number of parities you want to eat every day, combined with the purchase method of the previous day to determine which purchase method to use, here you need to make a special judgment on the last day.
Here flag is used to indicate the previous day ’s Purchase method, 0 means using method 1, 1 means method 2, you currently have a voucher in your hand, you must use it on the day, flag2 indicates whether there is a voucher and is useless, if it appears, it will output "NO" Method 1 can be used, that is, after subtracting yesterday's coupon, it must be an even number, otherwise output "NO".

Code

#include<bits/stdc++.h>
using namespace std;
  
//string str;

int main()
{
	int n,temp;
	cin>>n;
	bool flag=0,flag2=1;
	for(int i=0;i<n-1;i++)
	{		
		cin>>temp;
 		if(flag2)
		{
			if(flag)
			{
				temp-=1;
				if(temp<0)
				{
					flag2=0;//flag2倒了 
	 			}
				flag=0;
			}
			if( temp%2)flag=1;//奇数,采用方案二,立flag。 
		}
	}
		cin>>temp;
	if(flag2)
	{
 		if(flag)
		{
			temp-=1;
			if(temp<0)
			{
				flag2=0;
 			}
			flag=0;
		}
	}
	if(!flag2||temp%2)cout<<"NO"<<endl;
	else cout<<"YES"<<endl;	
	return 0;
	
}

to sum up

This question has a clear idea, but the details need to be considered clearly. At first, I wrote it without thinking carefully. Fortunately, after testing several sets of data, I found the flag2 problem. After adding it, the problem was solved.

Question C

Problem Description

Cosmic rays will propagate on an infinite two-dimensional plane (it can be seen as a two-dimensional grid), and the initial direction is upward by default. The cosmic ray will split after a certain distance is emitted, splitting two cosmic rays in the direction of 45 ° to the left and right of this direction, and the power will remain unchanged! Cosmic rays will split n times, and each split will advance ai unit length in the splitting direction.
Calculate the total number of positions that will be "hit down" to
input the number of times the cosmic ray will split (n <= 30), and the cosmic ray of the i-th split will continue to travel in its original direction length ai (ai <= 5).
The splitting method is shown in the figure:
Question C split method

Ideas

I used the idea of ​​BFS. Use a four-dimensional array to record whether the point has been passed. When the point is passed, the point is discarded. Otherwise, the point is added to the queue. The set storage point is used here, which eliminates the weight. Step, finally output the size of set

Code
#include <iostream>
#include<queue>
#include<cstring>
#include<set>
using namespace std;
//bool vis[400][400];
bool revis[400][400][8][33];
int length[100];

struct point
{
    int x;
    int y;
    int d;//0-7for 8个方向  0 up 1 ul 2 r 3dr 4 down   
    point(int a,int b,int c=0):x(a),y(b),d(c){};
    point(){};
    bool operator <(const point & a) const
	{
		if(x==a.x)return y<a.y;
		return x<a.x;
	}
};
set<point>mp; 
struct xy
{
    int x;
    int y;
}dxdy[8];
void initial()
{
    dxdy[0].x=0;
    dxdy[0].y=1;
    dxdy[1].x=1;
    dxdy[1].y=1;
    dxdy[2].x=1;
    dxdy[2].y=0;
    dxdy[3].x=1;
    dxdy[3].y=-1;
    dxdy[4].x=0;
    dxdy[4].y=-1;
    dxdy[5].x=-1;
    dxdy[5].y=-1;
    dxdy[6].x=-1;
    dxdy[6].y=0;
    dxdy[7].x=-1;
    dxdy[7].y=1;
}
int main()
{
   // memset(vis,0,sizeof(vis));
	memset(revis,0,sizeof(revis));
    int n;
    cin>>n;
    initial();
    for(int i=0;i<n;i++)
    {
        cin>>length[i];
    }
    queue<point> q;
    point start(200,200,0);
    int ans=0;
    q.push(start);
    for(int j=0;j<n;j++)
    {
        int k = q.size();
        while(k--)
        {
            point newpos = q.front();
            q.pop();
            for(int i=1;i<=length[j];i++)
            {
                newpos.x += dxdy[newpos.d].x;
                newpos.y += dxdy[newpos.d].y;
 
               // point  t(newpos.x,newpos.y);
				mp.insert({newpos.x,newpos.y});
            }
            if(j!=n-1)
            {
                if(revis[newpos.x][newpos.y][(newpos.d+1)%8][j]==0)
                {
                    point p1(newpos.x,newpos.y,(newpos.d+1)%8);
                    q.push(p1);
                    revis[newpos.x][newpos.y][(newpos.d+1)%8][j]=1;
                }
                if(revis[newpos.x][newpos.y][(newpos.d+7)%8][j]==0)
                {
                    point p2(newpos.x,newpos.y,(newpos.d+7)%8);
                    q.push(p2);
                    revis[newpos.x][newpos.y][(newpos.d+7)%8][j]=1;
                }
            }
        }
    }
    cout<<mp.size();
}
to sum up

This question made me deeply feel the lack of coding power. It took almost an hour to force a violent bfs algorithm to force the simulation, and it timed out as expected. Afterwards, I would like to consult an expert and find the correct way to repeat the problem under the guidance of the expert. Listen It is said that there is a dfs method, and learning is still needed.

Published 20 original articles · praised 3 · visits 458

Guess you like

Origin blog.csdn.net/qq_44893580/article/details/104972097