在这里插入代码片`#include <stdio.h>
int main()
{
int N;
scanf("%d",&N);
int a[N];
for(int i=1;i<=N;i++)
scanf("%d",&a[i]);
long long maxa=-10001;
int sum[200000];
for(int i=1;i<=N;i++)
{
if(sum[i-1]>0) sum[i] = sum[i-1]+a[i];
else sum[i] = a[i];
if(sum[i]>maxa)
maxa=sum[i];
}
printf("%lld",maxa);
return 0;
}
`
https://www.baidu.com/link?url=6LLRKNUQBiSM9zz1hwuV1RyQqmTbGv1_Innyegvbbq9FPugyNdwrj_Q_bmZiLV6og1EMotI1LcjbSXgOLuVDfa&wd=&eqid=b168ad530005e03b00000003609a51bc
Description
来源于POJ3704。
在某个字符串(长度不超过100)中有左括号、右括号和大小写字母;
规定(与常见的算数式子一样)任何一个左括号都从内到外与在它右边且距离最近的右括号匹配。
写一个程序,找到无法匹配的左括号和右括号,输出原来字符串,并在下一行标出不能匹配的括号。
不能匹配的左括号用"$“标注,不能匹配的右括号用”?"标注.
输入格式
输入包括多组数据,每组数据一行,包含一个字符串,只包含左右括号和大小写字母,字符串长度不超过100。
输出格式
对每组输出数据,输出两行。
第一行包含原始输入字符,第二行由"
"
,
"
?
"
和
空
格
组
成
,
"
","?"和空格组成,"
","?"和空格组成,"“和”?"表示与之对应的左括号和右括号不能匹配。
输入样例
((ABCD(x)
)(rttyy())sss)(
输出样例
((ABCD(x)
$$
)(rttyy())sss)(
? ?$
提示
读取多组数据时,可采用如下方法,其他scanf读到文件尾时会返回值EOF。
char s[205];
while(scanf("%s",s)!=EOF){}
#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
using namespace std;
#include<vector>
#include<string.h>
int main(void){
//定义s输入
//ans存放
//location定位
char s[105];
char ans[105];
vector<int>location;
//EOF写法
//从1开始写
while (cin>>s) {
//输入后这里还要先输出一次!!!
cout << s<<endl;
int length = strlen(s);
for (int i = 0; i < length; i++) {
//如果是'('先将序号i进到vector
if (s[i] == '(') {
location.push_back(i);
}
//如果是')'先检测vector是否为空
else if (s[i] == ')') {
// 如果非空就pop尾部一个
if (!location.empty()) {
location.pop_back();
}
// 空就让ans[序号]为?
else {
ans[i] = '?';
}
}
}
//再判断vector是否为空
//非空就即为未匹配的'(' 设置该序号为'$'
while (!location.empty()) {
int i = location.back();
ans[i] = '$';
location.pop_back();
}
for (int i = 0; i < length; i++) {
//输出 如果不是'?'也不是'$'就输出' '
if (ans[i] == '?' || ans[i] == '$')
cout << ans[i]; else
cout << ' ';
}
//要换行
cout << endl;
//处理完后清空存储
memset(ans, 0, sizeof(ans));
memset(s, 0, sizeof(s));
location.clear();
}
return 0;
}
Description
每年期末考试必考题目。
一个栈的进栈序列是a、b、c、d、e,则可能的出栈序列是( )。
A.abecd B.decba C.dceab D.cabde
输入两个整数序列,第一个序列表示栈的压入顺序,请判断第二个序列是否可能为该栈的弹出顺序。
假设压入栈的所有数字均不相等。例如序列1,2,3,4,5是某栈的压入顺序,序列4,5,3,2,1是该压栈序列对应的一个弹出序列,
但4,3,5,1,2就不可能是该压栈序列的弹出序列。(注意:这两个序列的长度是相等的)
输入格式
第一行一个整数n,表示输入序列的长度。(1<=n<=10000)
第二行n个整数,表示栈的压入顺序。
第三行n个整数,表示栈的出栈顺序。
输出格式
如果是弹出序列,输出yes,否则输出no。
输入样例
5
1 2 3 8 6
8 6 3 2 1
输出样例
yes
’‘`cpp`int main()
{
int n;
cin >> n;
SqStack L;
//一定要初始化建立栈
InitStack(L);
int e;
//先用两数组把进栈和出栈数存储
int* push = new int[n];
int* pop = new int[n];
for (int i = 0; i < n; i++) {
cin >> e;
push[i] = e;
}
for (int i = 0; i < n; i++) {
cin >> pop[i];
}
int k = 0;
for (int i = 0; i < n; i++) {
//边入栈push[i]边和出栈数组数判断
Push(L, push[i]);
//这里要用while,直到出栈数和顶部数不同为止
while (*L.top == pop[k])Pop(L, e),k++;
}
//最后 如果L.top和L.base相同则说明全部出栈
//否则说明无法出栈
if (L.top == L.base)cout << "yes"; else cout << "no";
return 0;
}\\\\\\\\\\\\while哪里是细节
`
18714 迷宫问题
时间限制:1000MS 代码长度限制:10KB
提交次数:0 通过次数:0
题型: 编程题 语言: G++;GCC
Description
迷宫是一个n*m的矩阵,玩家需要迷宫入口(坐标1,1)出发,寻找路径走到出口(n,m)。
请判断玩家能否从迷宫中走出。
输入格式
第一行两个整数n和m,代表n行m列。(1<=n,m<=10)
下面n行每行m个字符,0代表可以通行,1代表不可以通行。
输出格式
如果能从迷宫走出,输出yes,否则输出no。
输入样例
8 8
00100010
00100010
00001100
01110000
00010000
01000100
01110110
00001000
输出样例
yes
最长路径==关键路径。
这道题目我们可以用最短路径的求法来求,我们只需要将边权变为负数即可。输出时再变回正数。
这里注意一下:Dijkstra算法不适用于负权的图。
所以这一题,我们用floyd算法求最长路径。
代码如下:
#include<iostream>
#include<algorithm>
#include<cmath>
#include<cstring>
using namespace std;
int map1[105][105];
int dist[105][105];
int n,m;
void floyd()
{
int i,j,k;
for(k=1;k<=n;k++)
for(i=1;i<=n;i++)
for(j=1;j<=n;j++)
if(map1[i][j]>map1[i][k]+map1[k][j])
map1[i][j]=map1[i][k]+map1[k][j];
}
int main()
{
cin>>n>>m;
memset(map1,0x3f3f3f3f,sizeof(map1));
for(int i=0;i<105;i++)
map1[i][i]=0;
for(int i=1;i<=m;i++)
{
int x,y,z;
cin>>x>>y>>z;
map1[x][y]=-z;
}
floyd();
cout<<-map1[1][n]<<'\n';
return 0;
}
#include<iostream>
#include<algorithm>
using namespace std;
int d[500000];
int main()
{
int n;
cin>>n;
for(int i=0;i<n;i++)
cin>>d[i];
int D=n/2; //初始增量为n/2。
while(D>0) //当增量大于0时,进入循环
{
for(int k=0;k<n;k++) //循环多次
{
for(int i=0;i<n;i++)
{
if(i+D<n) //消除越界情况
{
if(d[i]>d[i+D]) //如果左边的较大,则调用swap函数交换
{
swap(d[i],d[i+D]); //头文件algorithm中的函数
}
}
}
}
for(int j=0;j<n;j++)
cout<<d[j]<<" ";
cout<<endl;
D=D/2; //增量变为原来的二分之一
}
return 0;
}
//希尔排序,实际上是在i+D,i+D+D,i+D+D+D,组成的
//块中,进行排序一次。然后减小D,再进行排序
18931 分形
时间限制:1000MS 代码长度限制:10KB
提交次数:0 通过次数:0
题型: 编程题 语言: G++;GCC
Description
分形,具有以非整数维形式充填空间的形态特征。
通常被定义为“一个粗糙或零碎的几何形状,可以分成数个部分,且每一部分都(至少近似地)是整体缩小后的形状”,即具有自相似的性质。
现在,定义“盒子分形”如下:
一级盒子分形:
X
二级盒子分形:
X X
X
X X
如果用B(n - 1)代表第n-1级盒子分形,那么第n级盒子分形即为:
B(n - 1) B(n - 1)
B(n - 1)
B(n - 1) B(n - 1)
你的任务是绘制一个n级的盒子分形。
输入格式
输入一个不大于6的正整数n,代表要输出的盒子分形的等级。
输出格式
使用“X”符号输出对应等级的盒子分形。
输入样例
4
输出样例
X X X X X X X X
X X X X
X X X X X X X X
X X X X
X X
X X X X
X X X X X X X X
X X X X
X X X X X X X X
X X X X
X X
X X X X
X X
X
X X
X X X X
X X
X X X X
X X X X X X X X
X X X X
X X X X X X X X
X X X X
X X
X X X X
X X X X X X X X
X X X X
X X X X X X X X
洛谷5-19:
#include<bits/stdc++.h>
using namespace std;
struct eee {//请你不要在意我结构体的名字
int zf,a,b,c;
string s;
};
bool cmp(eee a,eee b) {
return a.zf>b.zf;//将总分从大到小排序
}
eee x[1001];
int n;
int main() {
scanf("%d",&n);
for(int i=1; i<=n; ++i) {
cin>>x[i].s>>x[i].a>>x[i].b>>x[i].c;
x[i].zf=x[i].a+x[i].b+x[i].c;//算出总分
}
sort(x+1,x+n+1,cmp);//调用sort函数并调用自定义函数cmp
cout<<x[1].s<<" "<<x[1].a<<" "<<x[1].b<<" "<<x[1].c<<endl;//输出第一名的名字和各项成绩
return 0;
}
非常厉害,sort()函数可以直接从小到大排序,然后也可以自己定义函数来排结构体,也可以自己定义函数来逆排序!
string s;
可以直接比较s1与s2!用><号来比较,如果是字符abcd就可以按头为
为首依次比较大小!(头为准)
快速排序算法
递归贼烦!!!!!!!!!!!!!
#include<iostream>
using namespace std;
int n;
int Partition(int a[],int low,int high)
{
int x;
x=a[low];
while(low<high)
{
while(x<=a[high]&&low<high)
high--;
a[low]=a[high];
while(a[low]<=x&&low<high)
low++;
a[high]=a[low];
}
a[low]=x;
return low;
}
int QSort(int a[],int low,int high)
{
if(low<high)
{
int k=Partition(a,low,high);
int i;
for(i=1;i<=n;i++)
{
cout<<a[i]<<' ';
}
cout<<endl;
QSort(a,low,k-1);
QSort(a,k+1,high);
}
}
int main()
{
cin>>n;
int i,a[n];
for(i=1;i<=n;i++)
{
cin>>a[i];
}
int low=1,high=n;
QSort(a,low,high);
return 0;
}
//新的快排,洛谷
https://www.luogu.com.cn/problem/solution/P1177
#include<iostream>
using namespace std;
int n,a[1000001];
void qsort(int l,int r)//应用二分思想
{
int mid=a[(l+r)/2];//中间数
int i=l,j=r;
do{
while(a[i]<mid) i++;//查找左半部分比中间数大的数
while(a[j]>mid) j--;//查找右半部分比中间数小的数
if(i<=j)//如果有一组不满足排序条件(左小右大)的数
{
swap(a[i],a[j]);//交换
i++;
j--;
}
}while(i<=j);//这里注意要有=
if(l<j) qsort(l,j);//递归搜索左半部分
if(i<r) qsort(i,r);//递归搜索右半部分
}
int main()
{
cin>>n;
for(int i=1;i<=n;i++) cin>>a[i];
qsort(1,n);
for(int i=1;i<=n;i++) cout<<a[i]<<" ";
}
多种排序
我来搞事了 (=゚ω゚)ノ
写了6种基本的排序,基本可以囊括所有排序思想了
快排与希尔(当然希尔还有种复杂版)是最好写的也是最好用的。快排可移植能力强,可以配合swap函数及自身完成转移下标等操作(不用struct的话),另外快排是寻找第k大问题的好工具;希尔排序直接写在main函数中,短小精悍,但时间复杂度emmmm...
没写冒泡排序,个人认为其和插入排序结构差不多
选择排序有链表的思想,故在这提出
桶排序时间是极优的,但空间是个问题
归并排序是均衡了时间空间的排序,时间较快排好,但一般我不想写将其作为大轴子( ̄▽ ̄")
堆排序未出现
优化
快排:可以两边同时进行
快排:可以设定排序长度(保证每个区间的最大值不大于下个区间的最小值),然后再用插入排序处理短序列
选择排序:也是2边同时进行,换为先排max和min,一趟循环就只用i/2(i=n,n-1,...,2,1)
别的优化欢迎补充
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <math.h>
#include <ctype.h>
#include <time.h>//我要搞事 (`・ω・´)
#define max(A, B) ((A > B) ? A : B)
#define min(A, B) ((A < B) ? A : B)
void swap(int arr[], int i, int j);
void QuickSort(int arr[], int left, int right);
void ShellSort(int arr[], int left, int right);
void InsertSort(int arr[], int left, int right);
void BucketSort(int arr[], int left, int right);
void SelectSort(int arr[], int left, int right);
void Merge(int arr[], int left, int mid, int right);
void MergeSort(int arr[], int left, int right);
int main()
{
int n;
int *arr;
int i;
scanf("%d", &n);
arr = (int*)malloc(sizeof(int) * (n + 1));
for (i = 1; i <= n; i++)
scanf("%d", arr + i);
/*想测试人品吗?srand((unsigned)time(0));
int temp = rand() % 6; //骚一波 ≖‿≖✧ ps:拼人品,有可能过不了
switch (temp) {
case 0:
QuickSort(arr, 1, n);
break;
case 1:
ShellSort(arr, 1, n);
break;
case 2:
InsertSort(arr, 1, n);
break;
case 3:
BucketSort(arr, 1, n);
break;
case 4:
SelectSort(arr, 1, n);
break;
case 5:
MergeSort(arr, 1, n);
break;
default:
printf("error: rand()? or mod Σ( ° △ °|||)︴\n");
break;
}*/
MergeSort(arr, 1, n);
for (i = 1; i <= n; i++)
printf("%d ", arr[i]);
return 0;
}
void swap(int arr[], int i, int j)
{
int temp;
temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
void QuickSort(int arr[], int left, int right)
{
int i, pivot;
if (left >= right)
return;
pivot = left;
swap(arr, left, (left + right) / 2);
for (i = left + 1; i <= right; i++) //单边搜索,可以该为双向搜索(据说快点( ° ▽、° ))
if (arr[i] < arr[left])
swap(arr, i, ++pivot);
swap(arr, left, pivot);
QuickSort(arr, left, pivot - 1);
QuickSort(arr, pivot + 1, right);
}
void ShellSort(int arr[], int left, int right)
{
int gap, i, j;
//ShellSort因为我只写过0——n-1的(最标准的),可能有点小bug(不过应该没错吧 (*´Д`*) )
for (gap = (left + right) / 2; gap > 0; gap /= 2)
for (i = gap; i <= right; i++)
for (j = i - gap; j > 0 && arr[j] > arr[j + gap]; j -= gap)
swap(arr, j, j + gap);
}
void InsertSort(int arr[], int left, int right)
{
int i, v;
for (i = left; i <= right; i++) {
v = arr[i];
int l = left, r = i;
int j;
while (l < r) {//在l与r之间插入排序,可以理解为解决子问题1→2→...→n
int mid = (l + r) / 2;
if (arr[mid] <= v)
l = mid + 1;
else
r = mid;
}
for (j = i - 1; l <= j; j--)
arr[j + 1] = arr[j];
arr[l] = v;
}
}
void BucketSort(int arr[], int left, int right)
{
int i, v;
static int cnt[123456] = { 0 };
for (i = left, v = 0; i <= right; i++) {
v = max(v, arr[i]);//部分优化:统计最大值,不用遍历所有桶,但空间仍是个问题╮(╯▽╰)╭
cnt[arr[i]]++;
}
v++;
while (v-- > 0)
while (cnt[v]-- > 0)
arr[--i] = v;
}
void SelectSort(int arr[], int left, int right)
{
int i, j, k;
for (i = left; i <= right; i++) {
for (j = k = i; j <= right; j++) //可以理解为对k进行选择,将k的指向第i-left小的
if (arr[j] < arr[k])
k = j;
if (i < k)
swap(arr, i, k);
}
}
void Merge(int arr[], int left, int mid, int right)
{
//merge arr[L,M](sorted) and arr(M,R](sorted) into arr[L,R]
static int p = 1, que[123456] = { 0 };
int pl = left, pr = mid;
int ql = mid + 1, qr = right;
while (pl <= pr || ql <= qr) {
if ((ql > qr) || (pl <= pr && arr[pl] <= arr[ql])) //有点麻烦的判断,要考虑arr已提取完的情况
que[p++] = arr[pl++];
else
que[p++] = arr[ql++];
}
while (left <= right)
arr[right--] = que[--p];
}
void MergeSort(int arr[], int left, int right)
{
if (left >= right)
return;
int mid = (left + right) / 2;
MergeSort(arr, left, mid);
MergeSort(arr, mid + 1, right);
Merge(arr, left, mid, right);//二分递归
}
学习一下STL函数
我们可以用STL里一个叫做nth_element的东西。
这个东西的用法是这样:
nth_element(a+l,a+k,a+r);
这样它会使aa这个数组中,区间[l,r)[l,r)内的第kk小的元素处在第kk个位置上(相对位置),但是它并不保证其他元素有序!它的复杂度是O(r-l+1)O(r−l+1),即区间长。
那么这部分的代码如下:
scanf("%d%d",&n,&k);
for(int i=1;i<=n;i++) {
scanf("%d",&a[i]);
}
k++;
nth_element(a+1,a+k,a+n+1);
printf("%d",a[k]);