【1月6日第10天】 AcWing寒假每日一题2023

本文介绍了多种算法题目,包括统计字符出现次数、上课睡觉问题、学分绩点计算、奶牛大学问题、选数异或、求和、数位排序以及快速选择。这些题目涉及到了排序算法的实现,如快速排序和快速选择,并讨论了它们的时间复杂度。
摘要由CSDN通过智能技术生成

AcWing寒假每日一题2023


4261. 孤独的照片

4261. 孤独的照片
#include <iostream>
#include <algorithm>
#include <cstring>
#define x first
#define y second
using namespace std;

typedef long long ll;


const int N = 100010;

int T, n;
string s;
ll ans;

int max(int a, int b) {
	return a > b ? a : b;
}


int main() {
	scanf("%d", &n);
	cin >> s;
	for (int i = 0; i < n; i++) {
		int l = 0, r = 0;
		int j = i - 1;
		while (j >= 0 && s[i] != s[j]) {
			l++, j--;
		}
		j = i + 1;
		while (j < n && s[i] != s[j]) {
			r++, j++;
		}
		ans += (ll) r * l + max(0, l-1) + max(0, r-1);
	}
	cout << ans << endl;
	return 0;
}

3400. 统计次数

3400. 统计次数

#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;

int n, k, ans;

int solve(int x) {
    int res = 0;
    while (x) {
        if (x % 10 == k) res++;
        x /= 10;
    }
    return res;
}

int main() {
    cin >> n >> k;
    for (int i = 1; i <= n; i++) {
        ans += solve(i);
    }
    cout << ans << endl;
}
4366. 上课睡觉

4366. 上课睡觉

#include <iostream>
#include <algorithm>
#include <cstring>
using namespace std;

const int N = 100010;

int T, n;
int a[N];

bool check(int y) {
	int sum = 0;
	for (int i = 0; i < n; i++) {
		sum += a[i];
		if (sum == y) sum = 0;
		else if (sum > y) return false;
	}
	return true;
}

void solve() {
	cin >> n;
	int sum = 0, mmax = 0;
	for (int i = 0; i < n; i++) {
		scanf("%d", &a[i]);
		mmax = max(mmax, a[i]);
		sum += a[i];
	}
    if (mmax == 0) {
        cout << 0 << endl;
        return ;
    }
	for (int i = mmax; i <= sum; i++) {
	    if (sum % i == 0) {
	        if (check(i)) {
			    cout << n - sum/i << endl;
			    break;
		    }
	    }
	}

}

int main() {
	cin >> T;
	while (T--) solve();
	return 0;
}
3443. 学分绩点

3443. 学分绩点

#include <iostream>
#include <cstring>
#include <algorithm>

using namespace std;
int n;
const int N = 1010;
int a[N];

double check(int s) {
    if (s >= 90) return 4.0;
    else if (s >= 85) return 3.7;
    else if (s >= 82) return 3.3;
    else if (s >= 78) return 3.0;
    else if (s >= 75) return 2.7;
    else if (s >= 72) return 2.3;
    else if (s >= 68) return 2.0;
    else if (s >= 64) return 1.5;
    else if (s >= 60) return 1.0;
    else return 0;
}

int main() {
    cin >> n;
    double s = 0, ssum = 0;
    for (int i = 0; i < n; i++) {
        cin >> a[i];
        ssum += a[i];
    }
    for (int i = 0; i < n; i++) {
        double score;
        cin >> score;
        s += check(score) * a[i];
    }
    
    printf("%.2lf", s / ssum);
    
    return 0;
}
4818. 奶牛大学

4818. 奶牛大学

#include <iostream>
#include <cstring>
#include <algorithm>

using namespace std;

typedef long long LL;
const int N = 100010;
int n;
LL ans, mon;
LL a[N];

int main() {
    scanf("%d", &n);
    for (int i = 1; i <= n; i++) scanf("%lld", &a[i]);
    
    sort(a + 1, a + n + 1);
    
    for (int i = 1; i <= n; i++) {
        LL res = a[i] * (n - i + 1);
        if (res > ans) {
            ans = res;
            mon = a[i];
        }
    }
    cout << ans << ' ' << mon << endl;
    return 0;
}
4645. 选数异或

4645. 选数异或

#include <iostream>
#include <cstring>
#include <algorithm>

using namespace std;

const int N = 100010, M = (1 << 20) + 10;

int last[M], g[N];

int n, m, x;

int main() {
    scanf("%d%d%d", &n, &m, &x);
    for (int i = 1; i <= n; i++) {
        int a;
        scanf("%d", &a);
        g[i] = max(g[i - 1], last[a ^ x]);
        last[a] = i;
    }
    
    while (m--) {
        int l, r;
        scanf("%d%d", &l, &r);
        if (g[r] >= l) puts("yes");
        else puts("no");
    }
    
    return 0;
}
4644. 求和

4644. 求和

#include <iostream>
#include <cstring>
#include <algorithm>

using namespace std;

typedef long long ll;

const int N = 200010;

int a[N];
int n;
ll sum, ans;

int main() {
    scanf("%d", &n);
    for (int i = 0; i < n; i++) {
        scanf("%d", &a[i]);
        sum += a[i];
    }
    
    for (int i = 0; i < n; i++) {
        sum -= a[i];
        ans += (ll) a[i] * sum;
    }
    
    printf("%lld\n", ans);
    
    return 0;
}
4653. 数位排序

4653. 数位排序

快速排序 O ( n l o g n ) O(nlogn) O(nlogn)
#include <iostream>
#include <algorithm>
#include <cstring>

using namespace std;

const int N = 1000010;

int n, m;
int w[N];

int main() {
	scanf("%d%d", &n, &m);
	for (int i = 1; i <= n; i++)
		w[i] = i;
	sort(w + 1, w + n + 1, [](int a, int b) {
		int s1 = 0, s2 = 0, x = a, y = b;
		while (x) s1 += x % 10, x /= 10;
		while (y) s2 += y % 10, y /= 10;
		if (s1 != s2) return s1 < s2;
		return a < b;
	});

	printf("%d\n", w[m]);

	return 0;
}
快速选择 O ( n ) O(n) O(n)
#include <iostream>
#include <algorithm>
#include <cstring>

using namespace std;

const int N = 1000010;

int n, m;
int w[N], s[N];
int main() {
	scanf("%d%d", &n, &m);
	for (int i = 1; i <= n; i++) {
		w[i] = i;
		for (int j = i; j; j /= 10) {
			s[i] += j % 10;
		}
	}
	nth_element(w + 1, w + m, w + n + 1, [&](int a, int b) {
		if (s[a] != s[b]) return s[a] < s[b];
		return a < b;
	});

	printf("%d\n", w[m]);

	return 0;
}
手写快速选择 O ( n ) O(n) O(n)
#include <iostream>
#include <algorithm>
#include <cstring>

using namespace std;

const int N = 1000010;

int n, m;
int w[N], s[N];

bool cmp(int a, int b) {
    if (s[a] != s[b]) return s[a] < s[b];
	return a < b;
}

int quick_select(int l, int r, int k) {
    if (l == r) return w[l];
    int i = l - 1, j = r + 1, x = w[i + j >> 1];
    while (i < j) {
        do i++; while (cmp(w[i], x));
        do j--; while (cmp(x, w[j]));
        if (i < j) swap(w[i], w[j]);
    }
    if (k <= j) return quick_select(l, j, k);
    else return quick_select(j + 1, r, k);
}

int main() {
	scanf("%d%d", &n, &m);
	for (int i = 1; i <= n; i++) {
		w[i] = i;
		for (int j = i; j; j /= 10) {
			s[i] += j % 10;
		}
	}


	printf("%d\n", quick_select(1, n, m));

	return 0;
}
4655. 重新排序

4655. 重新排序

#include <iostream>
#include <cstring>
#include <algorithm>

using namespace std;
typedef long long ll;

const int N = 100010;

int n, m;
int a[N], c[N];


int main() {
    scanf("%d", &n);
    for (int i = 1; i <= n; i++) 
        scanf("%d", &a[i]);
        
    scanf("%d", &m);
    for (int i = 0; i < m; i++) {
        int l, r;
        scanf("%d%d", &l, &r);
        c[l]++, c[r + 1]--;
    }
    
    for (int i = 1; i <= n; i++)
        c[i] += c[i - 1];
        
    ll ori = 0;
    for (int i = 1; i <= n; i++) {
        ori += (ll) c[i] * a[i];
    }
    
    sort(a + 1, a + n + 1);
    sort(c + 1, c + n + 1);
    ll now = 0;
    for (int i = 1; i <= n; i++) {
        now += (ll) c[i] * a[i];
    }
    
    printf("%lld\n", now - ori);
    return 0;
}
4652. 纸张尺寸

4652. 纸张尺寸

#include <iostream>
#include <cstring>
#include <algorithm>

using namespace std;

int a = 1189, b = 841;

int main() {
    char w;
    int num;
    scanf("%c%d", &w, &num);
    while (num--) {
        a /= 2;
        a ^= b, b ^= a, a ^= b;
    }
    printf("%d\n%d\n", a, b);
    return 0;
}
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值