牛客周赛 Round 51

A题:小红的同余

思路:

大水题

code:

inline void solve() {
     int m; cin >> m;
     cout << (m + 1) / 2 << endl;
	 return;
}

B题:小红的三倍数

思路:

一个数如果能够被三整除,那么其各位上的数之和肯定为三的倍数。

题目只是多了一个衔接操作,相当于一些数会乘上一些十的倍数,不影响整除性。

我们只要判断总和是否为三的倍数即可。

code:

inline void solve() {
     int n; cin >> n;
     int cur = 0;
     for (int i = 0; i < n; i ++ ) {
     	string s; cin >> s;
     	for (char c : s) cur += c - '0';
     }
     cout << (!(cur % 3) ? "YES\n" : "NO\n");
	 return;
}

C题:小红充电

思路:

分类讨论, 要想充满电,那你充电的时候肯定不会玩手机

因为有快充存在,还存在一种先玩手机到快充线进行快充充满的情况。

如果一开始就能快充,就直接快充

code:

inline void solve() {
	 double ans;
     double x, y, t, a, b, c; cin >> x >> y >> t >> a >> b >> c;
     if (x <= t) ans = (100 - x) / c;
     else {
     	ans = min((100 - x) / b, (x - t) / y + (100 - t) / c);
     }
     cout << fixed << setprecision(7) << ans << endl;
	 return;
}

D题:小红的gcd

思路:

辗转相除法

gcd(a, b) = gcd(b, a % b)

code:

inline void solve() {
     string s; int b;
     cin >> s >> b;
     int a = 0;
     for (char c : s) {
         a = ((ll)a * 10 + (c - '0')) % b;
     }
     cout << __gcd(b, a) << endl;
	 return;
}

E题:小红走矩阵

思路:

最短路

code:

struct node {
    int dis; 
    PII point;
    bool operator > (const node &a) const {
        return dis > a.dis;
    }
};
int dx[] = {-1, 1, 0, 0}, dy[] = {0, 0, -1, 1};
inline void solve() {
     int n; cin >> n;
     vector<vector<int>> a(n + 1, vector<int>(n + 1));
     for (int i = 1; i <= n; i ++ ) {
     	for (int j = 1; j <= n; j ++ ) {
     		cin >> a[i][j];
     	}
     }
     priority_queue<node, vector<node>, greater<node>> q;
     vector<vector<int>> d(n + 1, vector<int>(n + 1, 1e9 + 7));
     q.push({0, {1, 1}});
     d[1][1] = a[1][1];
     map<PII, int> vis;
     while (q.size()) {
         PII cur = q.top().point; q.pop();
         if (vis[cur]) continue;
         vis[cur] = 1;
         int x = cur.first, y = cur.second;
         for (int i = 0; i < 4; i ++ ) {
             int nx = x + dx[i], ny = y + dy[i];
             if (nx >= 1 && nx <= n && ny >= 1 && ny <= n) {
                 if (d[nx][ny] > max(d[x][y], a[nx][ny])) {
                     d[nx][ny] = max(d[x][y], a[nx][ny]);
                     q.push({d[nx][ny], {nx, ny}});   
                 }
             }
         }
     }
     cout << d[n][n] << endl;
	 return;
}

F题:小红的数组 

思路:

区间问题,上线段树

不知道为啥,感觉写过了。

code:

const int N = 5e5 + 9;
struct node {
	int l, r;
	ll sum;
	ll mx, mn;
	ll lmx, rmx, lmn, rmn;
} tr[4 * N];
int a[N];
void pushup(node &T, node L, node R) {
	T.sum = L.sum + R.sum;
	T.lmx = max(L.lmx, L.sum + R.lmx);
	T.rmx = max(R.rmx, R.sum + L.rmx);
	T.lmn = min(L.lmn, L.sum + R.lmn);
	T.rmn = min(R.rmn, R.sum + L.rmn);
	T.mx = max({L.mx, R.mx, L.rmx + R.lmx});
	T.mn = min({L.mn, R.mn, L.rmn + R.lmn});
}
void pushup(int u) {
	node L = tr[u << 1], R = tr[u << 1 | 1];
	pushup(tr[u], L, R);
}
void build(int u, int l, int r) {
	tr[u] = {l, r};
	if (l == r) {
		tr[u] = {l, r, a[l], a[l], a[l], a[l], a[l], a[l], a[l]};
		return;
	}
	int mid = l + r >> 1;
	build(u << 1, l, mid), build(u << 1 | 1, mid + 1, r);
	pushup(u);
}
node query(int u, int l, int r) {
	if (tr[u].l >= l && tr[u].r <= r) {
		return tr[u];
	}
	int mid = tr[u].l + tr[u].r >> 1;
	if (l > mid) return query(u << 1 | 1, l, r);
	if (r <= mid) return query(u << 1, l, r);
	node T;
	pushup(T, query(u << 1, l, r), query(u << 1 | 1, l, r));
	return T;
}
inline void solve() {
     int n; cin >> n;
     for (int i = 1; i <= n; i ++ ) cin >> a[i];
     build(1, 1, n);
     int q; cin >> q;
     while (q -- ) {
     	int l, r; cin >> l >> r;
     	node T = query(1, l, r);
     	cout << max(T.mx, abs(T.mn)) << endl;
     }
	 return;
}

  • 7
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值