1下-21-5月-1

在这里插入代码片`#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]);
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值