比赛入口
B 麻烦的杰西
做法:单调栈经典题,在做的时候再一次忘记单调栈的实现,于是找了一块板子耻辱过了,后面还是得补一补单调栈啊,咕咕咕~
代码:
//最大矩形面积
#include <iostream>
#include <cstdio>
using namespace std;
typedef long long LL;
#define N 100005
LL ans,a[N];
int n,top;
int L[N], R[N];
struct node
{
LL x;
int pos;
node (LL a = 0, int b = 0):x(a), pos(b){}
}st[N];
int main()
{
while (~scanf("%d", &n))
{
for (int i=1;i<=n;i++)
scanf("%lld", &a[i]);
top = 0;
for (int i=1;i<=n;i++)
{
while (top > 0 && st[top].x > a[i])
{
R[st[top].pos] = i;
top--;
}
st[++top] = node(a[i], i);
}
while (top > 0)
R[st[top].pos] = n+1, top--;
top = 0;
for (int i=n;i>=1;i--)
{
while (top > 0 && st[top].x > a[i])
{
L[st[top].pos] = i;
top--;
}
st[++top] = node(a[i], i);
}
while (top > 0)
L[st[top].pos] = 0, top--;
ans = 0;
int ansi = 0;
for (int i=1;i<=n;i++) {
if(ans < a[i] * (R[i] - L[i] - 1)) {
ans = a[i] * (R[i] - L[i] - 1);
ansi = a[i];
}
}
printf("%d %lld\n", ansi, ans);
}
}
C 最大模数
做法:打个表看了一下,很明显能发现规律。奇数的时候是n*(n-1),偶数的时候是n*(n-2)。
代码:
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
int main () {
LL n, res;
while(~scanf("%lld", &n)) {
if(n & 1) res = n * (n - 1);
else res = n * (n - 2);
printf("%lld\n", res);
}
return 0;
}
D 米多立亚
做法:只有三种交换方式,要使得字符串字典序最小,输出能够得到的最小字典序的字符串。这道题如果要我来想,我肯定想不出来。其实可以发现,0和2的相对位置是不变的,只有1是可以改变其相对位置的,所以只要把所有的1放在第一个2前面就好啦~
代码:
#include<bits/stdc++.h>
#define fio ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
#define lson rt<<1, l, mid
#define rson rt<<1|1, mid+1, r
using namespace std;
typedef long long LL;
typedef pair<LL, int> pli;
typedef pair<int, int> pii;
typedef pair<LL, LL> pll;
typedef pair<double, double> pdd;
typedef map<char, int> mci;
typedef map<string, int> msi;
template<class T>
void read(T &res) {
int f = 1; res = 0;
char c = getchar();
while(c < '0' || c > '9') { if(c == '-') f = -1; c = getchar(); }
while(c >= '0' && c <= '9') { res = res * 10 + c - '0'; c = getchar(); }
res *= f;
}
int main() {
fio
string s;
while(cin >> s) {
int len = s.size();
int cnt = 0;
for(int i = 0; i < len; ++i) {
if(s[i] == '1') cnt++;
}
int flag = 1;
for(int i = 0; i < len; ++i) {
if(s[i] != '1') {
if(s[i] == '2') {
if(flag) {
flag = 0;
for(int j = 0; j < cnt; ++j) printf("1");
}
}
printf("%c", s[i]);
}
}
puts("");
}
return 0;
}
I 师姐我想要红包
做法:洛谷吃奶酪原题,要求最短需要多少路程走遍所有的点,点数很小,直接爆搜就可。
代码:
#include<bits/stdc++.h>
#define fio ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
#define lson rt<<1, l, mid
#define rson rt<<1|1, mid+1, r
using namespace std;
typedef long long LL;
typedef pair<LL, int> pli;
typedef pair<int, int> pii;
typedef pair<LL, LL> pll;
typedef map<char, int> mci;
typedef map<string, int> msi;
template<class T>
void read(T &res) {
int f = 1; res = 0;
char c = getchar();
while(c < '0' || c > '9') { if(c == '-') f = -1; c = getchar(); }
while(c >= '0' && c <= '9') { res = res * 10 + c - '0'; c = getchar(); }
res *= f;
}
pii dian[20];
int n, vis[20];
double res;
double Dis(pii a, pii b) {
return sqrt((a.first-b.first) * (a.first-b.first) + (a.second-b.second) * (a.second-b.second));
}
void dfs(pii cur, int step, double mid) {
if(mid > res) return ;
if(step >= n) {
res = min(res, mid);
return ;
}
for(int i = 0; i < n; ++i) {
if(!vis[i]) {
vis[i] = 1;
dfs(dian[i], step+1, mid + Dis(cur, dian[i]));
vis[i] = 0;
}
}
}
int main() {
res = 10000000.0;
read(n);
for(int i = 0; i < n; ++i) {
read(dian[i].first); read(dian[i].second);
}
dfs(make_pair(0, 0), 0, 0);
printf("%.2f\n", res);
return 0;
}
K 钟Sir的任务
做法:也是求最少需要多少个操作才能使一串序列的字典序最小,这次是每个位置只能交换1次。由于数据范围很小,所以直接暴力(类似冒泡排序)就可,一旦满足交换的条件就交换。
代码:
#include<bits/stdc++.h>
#define fio ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
#define lson rt<<1, l, mid
#define rson rt<<1|1, mid+1, r
using namespace std;
typedef long long LL;
typedef pair<LL, int> pli;
typedef pair<int, int> pii;
typedef pair<LL, LL> pll;
typedef map<char, int> mci;
typedef map<string, int> msi;
template<class T>
void read(T &res) {
int f = 1; res = 0;
char c = getchar();
while(c < '0' || c > '9') { if(c == '-') f = -1; c = getchar(); }
while(c >= '0' && c <= '9') { res = res * 10 + c - '0'; c = getchar(); }
res *= f;
}
const int N = 103;
int a[N], vis[N];
int main() {
int t; read(t);
while(t--) {
int n; read(n);
memset(vis, 0, sizeof vis);
for(int i = 1; i <= n; ++i) read(a[i]);
int cnt = 0, flag = 1;
while(cnt < n - 1 && flag) {
flag = 0;
for(int j = n; j >= 1; --j) {
if(a[j] < a[j-1] && !vis[j-1]) {
vis[j-1]++;
swap(a[j], a[j-1]);
flag = 1; cnt++;
}
if(cnt >= n - 1) break;
}
}
for(int i = 1; i <= n; ++i) {
printf("%d ", a[i]);
}
puts("");
}
return 0;
}