每日算法

每日算法

those times when you get up early and you work hard; those times when you stay up late and you work hard; those times when don’t feel like working — you’re too tired, you don’t want to push yourself — but you do it anyway. That is actually the dream. That’s the dream. It’s not the destination, it’s the journey. And if you guys can understand that, what you’ll see happen is that you won’t accomplish your dreams, your dreams won’t come true, something greater will. mamba out


那些你早出晚归付出的刻苦努力,你不想训练,当你觉的太累了但还是要咬牙坚持的时候,那就是在追逐梦想,不要在意终点有什么,要享受路途的过程,或许你不能成就梦想,但一定会有更伟大的事情随之而来。 mamba out~

2020.3.27


最低通行费

动态规划

#include <iostream>
#include <algorithm>
#include <cstdio>

using namespace std;
const int N = 105;
const int INF = 0x3f3f3f3f;
int a[N][N] , f[N][N] , n;
 
int main()
{
	cin >> n;
	for(int i = 1;i <= n ;i ++)
	{
		for(int j = 1;j <= n ;j ++)
		{
			scanf("%d",&a[i][j]);
		}
	}
	fill(f[0],f[0] + N * N , INF);
	f[0][1] = 0;f[1][0] = 0;
	for(int i = 1;i <= n ;i ++)
	{
		for(int j = 1;j <= n ;j ++)
		{
			f[i][j] = min(f[i-1][j],f[i][j-1]) + a[i][j];
		}
	}
	cout << f[n][n] << endl;
	return 0;
} 

树状数组求逆序对(其实是个模板)

#include <iostream>
#include <cstdio>
#include <algorithm>
#define lowbit(x) (x & -x)
using namespace std;
typedef long long ll;
const int N = 500005;
int tr[N] ,rank[N], n;
ll ans = 0;
struct node{
	int val , num;	
}a[N];

void add(int x,int v)
{
	for(int i = x;i <= n ;i+=lowbit(i))tr[i] += v;
}

ll query(int x)
{
	ll ans = 0;
	for(int i = x; i ; i -= lowbit(i))ans += tr[i];
	return ans;
}

bool cmp(node a,node b)
{
	if(a.val == b.val)
	{
		return a.num < b.num;
	}else return a.val < b.val;
}
int main()
{
	cin >> n;
	for(int i = 1;i <= n ;i ++)
	{
		scanf("%d",&a[i].val);
		a[i].num = i;
	}
	stable_sort(a + 1,a + n + 1,cmp);
	
	for(int i = 1;i <= n ;i ++)
		rank[a[i].num] = i;
	
	for(int i = 1;i <= n ;i ++)
	{
		add(rank[i], 1);
		ans += i - query(rank[i]);
	}
	cout << ans <<endl;
	return 0;
}

P1126 机器人搬重物

细节巨多得一道题

  1. 扩充坐标 因为机器人是圆形
  2. 方向表示 上下左右四个方向可以进行转向
  3. 有了方向要避免原地打转导致死循环
  4. 0 和 边界都不能访问
  5. 存在起点和终点在一起得情况
  6. 不同方向得标程不一样
  7. 防止穿墙!!!!(调了好久)。。。
#include <iostream>
#include <algorithm>
#include <cstdio>
#include <string>
#include <queue>

using namespace std;
const int N = 55;

int sx , sy ,tx, ty , n , m;
char op; 
int a[N][N];
int dir[4][3][2] = {   
 {{-1,0},{-2,0},{-3,0}},
 {{0,1},{0,2},{0,3}},
 {{1,0},{2,0},{3,0}},
 {{0,-1},{0,-2},{0,-3}}
}; 
bool vis[N][N];
bool book[N][N][5];
// 0 1 2 3  代表四个方向 

struct node{
	int x, y , t;
	int op;
	node (){}
	node(int x,int y,int t,int op):x(x),y(y),t(t),op(op){}
};

void show()
{
	cout << endl;
	for(int i = 0;i <= n ;i ++)
	{
		for(int j = 0;j <= m; j++)
		{
			cout << a[i][j] << " ";
		}
		cout << endl;
	}
}
//整体向一个方向扩充
 
bool inmap(int x,int y)
{
	return x >= 1 && x < n && y >= 1 && y < m;
}

/*
 如何避免原地打转
  
*/
int ans = 0;
int bfs(node start)
{
	queue<node> q;
	q.push(start);
	book[sx][sy][start.op] = 1;
	vis[sx][sy] = 1;
	while(!q.empty())
	{
		node now = q.front();
		for(int i = 0;i < 3;i ++)
		{
			int op = now.op;
			int nx = now.x + dir[op][i][0];
			int ny = now.y + dir[op][i][1];
			if(a[nx][ny] == 1)break;
			if(inmap(nx,ny) && !vis[nx][ny] && a[nx][ny] == 0)
			{
				vis[nx][ny] = 1;
				if(nx == tx && ny == ty)
				{
				//	cout << "找到目标" << endl;
					return now.t + 1;;
				}
				q.push(node(nx,ny,now.t + 1,now.op));
			}
		}
		
		int r = (now.op + 1) % 4;
		int l = (now.op + 4 - 1) % 4;
		if(book[now.x][now.y][l] == 0)
		{
			book[now.x][now.y][l] = 1;
			q.push(node(now.x,now.y,now.t + 1,l)); 	
		}
		if(book[now.x][now.y][r] == 0)
		{
			book[now.x][now.y][r] = 1;
			q.push(node(now.x,now.y,now.t + 1,r));	
	    }
		
		q.pop();
	}
	return -1;
}
 
void turn(int x,int y)
{
	a[x-1][y-1] = 1;
	a[x-1][y]   = 1;
	a[x][y-1]   = 1;
}

void input()
{
	cin >> n >> m;
	for(int i = 1;i <= n ;i ++)
	{
		for(int j = 1;j <= m ;j ++)
		{
			scanf("%d",&a[i][j]);
			if(a[i][j]){
				turn(i,j);
			}
		}
	}
	node s = node();s.t = 0;char op;
	cin >> s.x >> s.y >> tx >> ty >> op;
	if(s.x == tx && s.y == ty)
	{
		cout << 0 << endl;
		return ;
	}
	switch(op)
	{
		case 'S':
		s.op = 2;break;
		case 'N':
		s.op = 0;break;
		case 'W':
		s.op = 3;break;
		case 'E':
		s.op = 1;break;	
	}
	ans = bfs(s); 
	cout << ans << endl;
}

void init()
{
	for(int i = 1;i <= n ;i ++)
	{
		for(int j = 1;j <= m ;j ++)
		{
			for(int k = 0;k < 5;k ++)
			{
				book[i][j][k] = 0;
			}
		}
	}
}
int main()
{
	init();
	input();
	return 0;
} 

P2372 yyy2015c01挑战算周长

#include <iostream>
#include <algorithm>
#include <cstdio>
#include <queue>
#include <string> 

using namespace std;
const int N = 25;

char a[N][N]; 
int  n , m , sx ,sy;
bool vis[N][N];
int dir[8][2]={
{1,0},{-1,0},{0,1},{0,-1},{1,1},{-1,-1},{1,-1},{-1,1}
};

bool inmap(int x,int y)
{
	return x >= 1 && x <= n && y >= 1 && y <= m;
}
int ans = 0;
void dfs(int x,int y)
{
	for(int i = 0;i < 8;i ++)
	{
		int nx = x + dir[i][0];
		int ny = y + dir[i][1];
		if(inmap(nx,ny) && !vis[nx][ny] && a[nx][ny] == 'X')
		{
			vis[nx][ny] = 1;
			dfs(nx, ny);
		}
		if(!inmap(nx,ny) && i < 4){
			ans++;continue;
		}
		if(inmap(nx,ny) && a[nx][ny] == '.' && i < 4){
			ans++;continue;
		}
	}
}

void input()
{
	string s;
	cin >> n >> m >> sx >> sy;
	for(int i = 1;i <= n ;i ++)
	{
		cin >> s;
		for(int j = 0;j < s.size() ;j ++)
		{
			a[i][j+1] = s[j];
		}
	}
	vis[sx][sy] = 1;
	dfs(sx,sy);
	cout << ans << endl;
}

int main()
{
	input();
	return 0;
}
原文地址:https://www.cnblogs.com/wlw-x/p/12585234.html