旅游观光
代码
#include <bits/stdc++.h>
using namespace std;
int main()
{
int n;
cin >> n;
cout << (n - 1) / 2 << endl;
return 0;
}
栈和排序
我们用mx倒着记录max(a[i+1],a[i])
然后,正着扫一遍,如果当前元素小于等于mx[i]的话,我们就将他放到栈内,如果大于mx[i]的话,就先放到栈内,然后在取出来。
解释:
我们正着看的时候,遇到每个字符不知道什么时候该输出,但是,我们想让大的先输出,小的后输出。这样才能让字典序尽可能的大。
那我们来看,如果当前元素比后面的所有元素都大的话,是不是就该输出了呢,这显然是对的。
这样,贪心的走出来,每一步都尽可能的让字典序最大,那整体来看也是最大的。
import java.util.*;
import java.io.*;
public class Main{
public static int[] solve(int[] a){
int n = a.length;
Stack<Integer> s = new Stack<Integer>();
int ct = 0;
int[] res = new int[n];
int[] mx = new int[n + 1];
for (int i = n - 1; i >= 0; i -- ){
mx[i] = Math.max(mx[i + 1], a[i]);
}
for (int i = 0; i < n; i ++ ){
int num = a[i];
if (num <= mx[i + 1])
s.push(num);
else {
res[ct ++ ] = num;
while (!s.isEmpty() && s.peek() > mx[i + 1]){
res[ct ++ ] = s.pop();
}
}
}
return res;
}
public static void main(String[] args){
Scanner in = new Scanner(System.in);
int n = in.nextInt();
int[] nums = new int[n];
for (int i = 0; i < n; i ++ ) {
nums[i] = in.nextInt();
}
int[] res = solve(nums);
System.out.print(res[0]);
for (int i = 1; i < n; i ++ ){
System.out.print(" " + res[i]);
}
}
}
最长回文
这个题,需要好好记住,一个好题。
我们给字符串扩充#后,i和j坐标,一个在前指着字符串A,一个在后两个位置处(因为有#),每次从当前i]
向后扩展p[i] + cnt
位,j向前扩展。记录最大匹配, 最后减一就是结果了。
#include <bits/stdc++.h>
using namespace std;
const int N = 400010;
int n;
char c[N], c1[N], c2[N];
int p1[N], p2[N];
int len;
void change(char *str);
void mannacher(char *str, int *p);
int query();
int main()
{
cin >> n;
len = n << 1 | 1;
// cout << len << endl;
mannacher(c1, p1);
mannacher(c2, p2);
printf("%d\n", query());
}
void change(char *str){
scanf("%s", c);
int ct = 0;
str[ct ++ ] = '$';
str[ct ++ ] = '#';
for (int i = 0; i < n; i ++ )
{
str[ct ++ ] = c[i];
str[ct ++ ] = '#';
}
}
void mannacher(char *str, int *p)
{
change(str);
int id = 0, mx = 0, reslen = 0, rescentre = 0;
for (int i = 1; i <= len; i ++ )
{
if (mx > i) p[i] = min(p[id * 2 - i], mx - i);
else p[i] = 1;
while (i - p[i] > 0 && str[i - p[i]] == str[i + p[i]]) p[i] ++;
if (mx < i + p[i])
{
mx = i + p[i];
id = i;
}
if (reslen < p[i])
{
reslen = p[i];
rescentre = i;
}
}
}
int query() {
int ans = 1;
for(int i = 2; i <= len; i++) {
int tmp = max(p1[i], p2[i - 2]);
while(c1[i - tmp] == c2[i + tmp - 2]) tmp++;
ans = max(ans, tmp);
}
return ans - 1;
}
// int query(){
// int ans = 1;
// for (int i = 2; i <= len; i ++ )
// {
// int tmp = max(p1[i], p2[i - 2]);
// while (c1[i - tmp] == c2[i - 2 + tmp]) tmp ++;
// // if (tmp == 4) puts("###########################");
// // if (tmp == 5) puts("((((((((((((((((((((((((((");
// // if (tmp == 6) puts("))))))))))))))))))))))))))");
// // if (tmp == 7) puts("-------------------------");
// // if (tmp == 9) puts("***************************");
// // for (int j = i, s = tmp; s > 0; s --, j -- ) cout << c1[j];
// // cout << endl;
// // for (int j = i - 2, s = tmp; s > 0; s --, j ++ ) cout << c2[j];
// // cout << endl;
// // cout << "=====================" << endl;
// ans = max(ans, tmp);
// // int tmp = max(p1[i], p2[i + 2]);
// // while (c1[i + tmp] == c2[i + 2 - tmp]) tmp ++;
// // ans = max(ans, tmp);
// if (tmp > len) break;
// }
// return ans - 1;
// }