网易 2020.9.5 笔试

A C AC AC 了,不过有些代码写得有些冗余,可以参考看看。

A

模拟左手右手和背包,放回去的部分用 s t a c k stack stack 维护就可以了。


#include<bits/stdc++.h>
#define pb push_back
#define mes(a, b) memset(a, b, sizeof a)
using namespace std;
typedef long long ll;
const ll mod = 1e9+7;
const int maxn = 1e6+10;
const double eps = 1e-9;
const ll inf = 1e18;
int T;
int n, m, k, x;
int a[maxn];
stack<int> s[110];
char c[10], d[10];
int get(int x){
    int ans;
    if(s[x].empty()) ans = a[x];
    else{
        ans = s[x].top(); s[x].pop();
    }
    return ans;
}
int main(){
    while(~scanf("%d%d", &n, &m)){
        for(int i = 1; i <= n; i++){
            scanf("%d", &a[i]);
            while(!s[i].empty()) s[i].pop();
        }
        int l, r, b;
        while(m--){
            scanf("%d", &k);
            l = r = b = 0;
            for(int i = 1; i <= k; i++){
                scanf("%s%s", c, d);
                if(d[0] == 'k'){
                    if(c[0] == 'l') b += l, l = 0;
                    else b += r, r = 0;
                }
                else{
                    scanf("%d", &x);
                    if(c[0] == 'l'){
                        if(d[0] == 't')
                            l = get(x);
                        else if(d[0] == 'r'){
                            s[x].push(l);
                            l = 0;
                        }
                        
                    }
                    else{
                        if(d[0] == 't')
                            r = get(x);
                        else if(d[0] == 'r'){
                            s[x].push(r);
                            r = 0;
                        }
                        
                    }
                }
            }
            printf("%d\n", l+r+b);
        }
    }
    return 0;
}

B

记录一下上个状态和当前状态的差异,如果不会判到底要走几步就直接循环201次就好了,肯定不会错!


#include<bits/stdc++.h>
#define pb push_back
#define mes(a, b) memset(a, b, sizeof a)
using namespace std;
typedef long long ll;
const ll mod = 1e9+7;
const int maxn = 1e6+10;
const double eps = 1e-9;
const ll inf = 1e18;
int T;
int w, h, n, m;
char a[110][110], b[110][110], c[110][110], d[110][110];
int sx, sy, dx, dy;
void init(){
    for(int i = 1; i <= h; i++){
        for(int j = 1; j <= w; j++){
            c[i][j] = a[i][j];
        }
    }
}
int main(){
    scanf("%d", &T);
    while(T--){
        scanf("%d%d", &w, &h);
        for(int i = 1; i <= h; i++){
            scanf("%s", a[i]+1);
            for(int j = 1; j <= w; j++){
                c[i][j] = d[i][j] = a[i][j];
            }
        }
        scanf("%d%d", &m, &n);
        for(int i = 1; i <= n; i++) scanf("%s", b[i]+1);
        scanf("%d%d%d%d",&sx, &sy, &dy, &dx);
        int ans = 0;
        for(int i = 0; i <= 201;i++){  	//判边界T了无数发,干脆201
            init();		//更新为初始屏幕
            for(int j = 1, x = sx; j <= n; j++, x++){
                for(int k = 1, y = sy; k <= m; k++,y++){
                 //   printf("%d %d %c\n", x+dx*i, y+dy*i, b[j][k]);
                    if(0 >= x+dx*i || x+dx*i > h || y+dy*i <= 0 || y+dy*i > w) continue;
                    c[x+dx*i][y+dy*i] = b[j][k];	//C为当前应该的图案
                }
            }
            for(int j = 1; j <= h; j++){
                for(int k = 1; k <= w; k++){
                    if(d[j][k] != c[j][k]) ans++;	//d为上次的图形,算差异
                    d[j][k] = c[j][k];
                }
            }
        }
        printf("%d\n", ans);
    }
}

C

m a p map map 记录哪些位置可以走, s p f a spfa spfa 跑一遍最短路就可以了。

#include<bits/stdc++.h>
#define pb push_back
#define mes(a, b) memset(a, b, sizeof a)
using namespace std;
typedef long long ll;
const ll mod = 1e9+7;
const int maxn = 1e6+10;
const double eps = 1e-9;
const ll inf = 1e18;
int T;
int n, m, a, b;
map<int, map<int, int>> mp, vis;
vector<int> e[maxn];
int d[4][2] = {{-1, 0}, {1, 0}, {0, -1}, {0, 1}};
struct Node{
	int x, y, t;
};
int spfa(int sx, int sy,int ex,int ey){
	queue<Node> q; while(!q.empty()) q.pop();
	q.push(Node{sx, sy, 0});
	vis.clear();
	int x, y, dx, dy;
	Node now;
	while(!q.empty()){
		now = q.front(); q.pop();
		x = now.x; y = now.y;
		if(vis[x][y]) continue;
		vis[x][y] = 1;
		if(ex == x && ey == y) return now.t;
		for(int i = 0; i < 4; i++){
			dx = x+d[i][0];
			dy = y+d[i][1];
			if(!mp[dx][dy]) continue;
			q.push(Node{dx, dy, now.t+1});
		}
	}
	return -1;

}
int main(){
	scanf("%d", &T);
	while(T--){
		scanf("%d", &n); mp.clear();
		for(int i = 1; i <= n+1; i++) e[i].clear();
		int  x = 1, y = 1; mp[1][1] = 1;
		for(int i = 1; i <= n; i++){
			scanf("%d%d",&a,&b);
			if(b == -1) continue;
			x += d[a][0]; y += d[a][1];
			mp[x][y] = 1;
		}
		printf("%d\n",spfa(1, 1, x, y));
	}
	return 0;
}

D

因为 a i ∗ a i + 1 ≤ a i + 1 ∗ a i + 2 a_i*a_{i+1} \le a_{i+1} * a_{i+2} aiai+1ai+1ai+2
如果 a i + 1 a_{i+1} ai+1 是负数,则 a i ≥ a i + 2 a_i \ge a_{i+2} aiai+2
如果 a i + 1 a_{i+1} ai+1 是正数,则 a i ≤ a i + 2 a_i \le a_{i+2} aiai+2

如果正负数都有的时候,必须要正负数穿插着放,并且正数减小,负数增大。
如果只存在负数,那么就从大到小排
如果只存在正数,那么就从小到大排

  • 如果正数比负数多,则负数优先,后面的正数从小到大排
  • 如果负数比正数多,则正数优先,后面的负数从小到大排
#include<bits/stdc++.h>
#define pb push_back
#define mes(a, b) memset(a, b, sizeof a)
using namespace std;
typedef long long ll;
const ll mod = 1e9+7;
const int maxn = 1e6+10;
const double eps = 1e-9;
const ll inf = 1e18;
int T;
int n, m;
int a[maxn];
bool cmp(int x, int y){
    return x > y;
}
vector<int> x, y;

int main(){
    scanf("%d", &n);
    for(int i =1; i <= n; i++){
        scanf("%d",&a[i]);
        if(a[i] > 0) x.pb(a[i]);  //正数
        else y.pb(a[i]);		//负数
    }
    sort(x.begin(), x.end());
    sort(y.begin(), y.end());
    int l = x.size(), r = y.size();
    int len = min(l, r), cnt = 0;
    if(l > r){
        for(int i = 0; i < len; i++){
            a[++cnt] = y[i];
            a[++cnt] = x[len-i-1];
        }
        for(int i = len; i < l ;i++){
            a[++cnt] = x[i];
        }
    }
    else{
        sort(y.begin(), y.end(), cmp);
        for(int i = len-1; i >= 0; i--){
            a[++cnt] = x[i];
            a[++cnt] = y[i];
        }
        for(int i = len; i < r; i++){
            a[++cnt] = y[i];
        }
    }
   /* int flag = 1;
    for(int i = 2; i < n; i++){
        if(a[i-1] * a[i] > a[i] * a[i+1]) flag = 0;
    }
    puts(flag?"Yes":"No");*/
    for(int i = 1; i <= n; i++) printf("%d ",a[i]);
    puts("");
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值