2021.02.05学习总结

2021.02.05学习总结

早上7:00学习打卡
上午9:00 – 15:00(6h)
刷题,刷vj上的题;

I - Fence Repair

已知切割一块长度为 M 的木板(将其一分为二),其消耗的能量为 M。
请问,将一块长度为 X 的木板切割成 N 块(1≤ N ≤ 20000),且第 i 块长度为 Li (1≤ i ≤ N, 1≤ Li ≤50000 , L1+L2+…+LN= X) ,所需消耗的最小能量是多少?
Input
第一行为切割后木板的块数 N 。
之后的 N 行,第 i 行表示第 i 块木板的长度 Li 。
Output
输出一个整数,表示所需消耗的最小能量。
Sample Input
4
3
4
5
6
Sample Output
36

答辩的时候伍哥说是一道贪心,我用贪心做的时候一直runtime error。问了学长之后才知道这题是道优先队列。
优先队列知识补充
priority_queue< Type,Container,Functional>
Type就是数据的类型,Container就是容器类型(Container必须是用数组实现的容器,比如vector,deque等等不能用list,STL默认用vector),Functional就是比较的方式,当需要用自定义的数据类型时才需要传入这三个参数,使用基本类型时,只需要第一个就行了

#include <iostream>  
#include <queue>  
using namespace std;  
int main()  
{  
    priority_queue<int ,vector<int>,greater<int> > q;//定义优先队列   
    int n;  
    int num;  
    cin>>n;  
    for(int i=0;i<n;i++)  
    {  
        cin>>num;  
        q.push(num);  
    }  
    long long ans=0;  
    while(!q.empty())  
    {  
        int n1=q.top();  
        q.pop();  
        int n2=q.top();  
        q.pop();  
        ans+=n1+n2;  
        if(q.empty())  
            break;  
        q.push(n1+n2);  
    }  
      
    cout<<ans<<endl;  
    return 0;  
}  

K - Prime Path

hh学长酷爱素数,他经常自娱自乐,随机挑选两个四位的素数a,b。
游戏规则是:a可以通过改变某一位上的数字使其变成c,但只有当c也是四位的素数时才能进行这种改变。
hh学长可以很轻松的算出a最少经过多少次变化使其变为b,所以他相信你也可以。
例如:1033 -> 8179
1033
1733
3733
3739
3779
8779
8179
最少变换了6次。
Input
第一行输入整数T,表示样例数。 (T <= 100)
每个样例输入两个四位的素数a,b。(没有前导零)
Output
对于每个样例,输出最少变换次数,如果无法变换成b则输出"Impossible"。
Sample Input
3
1033 8179
1373 8017
1033 1033
Sample Output
6
7
0

思路:
先打个素数表,再用bfs解决。中途出现了这么个报错
error C2668: ‘pow’ : ambiguous call to overloaded function
在这里插入图片描述

错误原因:
正如错误提示一样,说了pow()函数的3种形式:

long double pow(long double,int)
float pow(float,int)
double pow(double,int)

对于所给的参数int,int,编译器无法判断应该匹配哪个函数,因此报错。

所以在用pow代码的时候,我就将第一个元素强制转换成浮点型
ac如下

#include<cstdio>
#include<queue>
#include<cmath>
#include<algorithm>
#include<iostream>
using namespace std;
int prime[10005];
struct node
{
	int num,step;
}; 
int bfs(int x,int y)
{
	node st;
	st.num = x;
	st.step = 0;
	queue<node> q;
	q.push(st);
	int vis[10005]={0};
	vis[x]=1;
	while(!q.empty())
	{
		st=q.front();q.pop();
		if(st.num==y)
		{
			return st.step;
		}
		for(int i=0;i<4;++i)
		{
			int base=pow((float)10,i);
			for(int j=0;j<10;++j)
			{
				if(i==0&&j==0)
				{
					continue;
				}
				int a=st.num-(st.num/base)%10*base+j*base;
				if(a>1000&&!vis[a]&&!prime[a])
				{
					vis[a]=1;
					node pt={a,st.step+1};
					q.push(pt);
				}
			}
		}
	}
	return -1;
}
int main()
{
	for(int i=2;i<10005;++i)
	{
		if(!prime[i])
		{
			for(int j=2*i;j<10005;j+=i)
			{
				prime[j]=1;
			}
		}
	}
	int T;
	cin>>T;
	while(T--)
	{
		int x,y;
		cin>>x>>y;
		int ans=bfs(x,y);
		if(ans!=-1)
		{
			printf("%d\n",bfs(x,y));
		}
		else
		{
			printf("Impossible\n");
		}
	}
	return 0;
}

G - Mine Sweeper

The game Minesweeper is played on an n by n grid. In this grid are hidden m mines, each at a distinct grid location. The player repeatedly touches grid positions. If a position with a mine is touched, the mine explodes and the player loses. If a positon not containing a mine is touched, an integer between 0 and 8 appears denoting the number of adjacent or diagonally adjacent grid positions that contain a mine. A sequence of moves in a partially played game is illustrated below.
Here, n is 8, m is 10, blank squares represent the integer 0, raised squares represent unplayed positions, and the figures resembling asterisks represent mines. The leftmost image represents the partially played game. From the first image to the second, the player has played two moves, each time choosing a safe grid position. From the second image to the third, the player is not so lucky; he chooses a position with a mine and therefore loses. The player wins if he continues to make safe moves until only m unplayed positions remain; these must necessarily contain the mines.
Your job is to read the information for a partially played game and to print the corresponding board.
Input
The first line of input contains a single postitive integer n <= 10. The next n lines represent the positions of the mines. Each line represents the contents of a row using n characters: a period indicates an unmined positon while an asterisk indicates a mined position. The next n lines are each n characters long: touched positions are denoted by an x, and untouched positions by a period. The sample input corresponds to the middle figure above.
Output
Your output should represent the board, with each position filled in appropriately. Positions that have been touched and do not contain a mine should contain an integer between 0 and 8. If a mine has been touched, all positions with a mine should contain an asterisk. All other positions should contain a period.
Sample Input
8
…*
.



…*…
..

xxx…
xxxx…
xxxx…
xxxxx…
xxxxx…
xxxxx…
xxx…
xxxxx…
Sample Output
001…
0013…
0001…
00011…
00001…
00123…
001…

思路:
输出时按照输出格式输出,将x的地方换成数字。
如果x的地方是雷,那么将全部的雷都要显示出来(即:模拟第三张图)。
遍历输出格式,如果是X,则一个dfs看周围有多少个雷并将数字替换X。如果X的地方就是一个雷, 那么flag标记一下。

代码

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
char mapp[15][15];
char book[15][15];
int n,k,flag;
void dfs(int x,int y)
{
    int xx[8]={-1,-1,-1,0,0,1,1,1};
    int yy[8]={-1,0,1,-1,1,-1,0,1};
    int cnt=0;
    for(int i=0;i<8;i++)
    {
        int a=x+xx[i];
        int b=y+yy[i];
        if(a>=0&&a<n&&b>=0&&b<k&&mapp[a][b]=='*')
        {
              cnt++;
        }
    }
    book[x][y]=cnt+'0';
    if(mapp[x][y]=='*')
      {
          flag=1;
      }
}
int main()
{
    while(cin>>n)
    {
        k=n;flag=0;
        for(int i=0;i<n;i++)
        {
            cin>>mapp[i];
        }
        for(int i=0;i<n;i++)
        {
            cin>>book[i];
        }
        for(int i=0;i<n;i++)
        {
            for(int j=0;j<n;j++)
            {
                if(book[i][j]=='x')
                {
                    dfs(i,j);
                }
            }
        }
        if(flag==1)
        {
            for(int i=0;i<n;i++)
                for(int j=0;j<n;j++)
                {
                    if(mapp[i][j]=='*')
                        book[i][j]='*';
                }
        }
        for(int i=0;i<n;i++)
            cout<<book[i]<<endl;
    }
}


C - Rails

https://vjudge.net/contest/419681#problem/C

就是n节火车按照一定顺序进站,看出站后的排列能否达到所给要求。
用栈模拟火车就ok。

#include<stack>
#include<stdio.h>
#include<iostream>
using namespace std;
stack<int> s;
int a[100000];
int main(){
	int n,i,t,k;
	while(cin>>n){
		if(n==0)
		break;
		while(cin>>a[0]){
			if(a[0]==0)			
				break;
			for(i=1;i<n;i++)	
				cin>>a[i];
           	t=1;
			k=0;
			s.push(t);
            while(k<n){
			   
               if(t<=n&&s.empty())   {
                  t++;
                  s.push(t);
		    	}
		    	else if(s.top()==a[k])   {
                  s.pop();
                  k++;
		    	}
		    	else if(s.top()!=a[k]&&t<n)   {
                  t++;
                  s.push(t);
    		   	}
    		   	else if(s.top()!=a[k])  {
				  break;   
				} 

     		}
     		if(!s.empty()){
     			pcout<<No<<endl;
			 } 
			 else
			 cout<<Yes<<endl;
			  while (!s.empty()) s.pop();
	}
		cout<<endl;
	}
}

晚上18:00-20:30(2h30m)
就读BILIBILI大学,数学专业。

总计8h30m

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值