1.基础用法
贴一个进制转换,感觉还不错的方法
原题可以在杭电oj上找到
https://vjudge.net/problem/HDU-2031/origin
代码
#include<iostream>
using namespace std;
char c[20]={'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};
signed main()
{
int a,b;
while(cin>>a>>b)
{
char num[510];
int j=0,t=0;
if(a<0)
{
t=1;
a=-a;
}
else if(a==0)num[j++]='0';
while(a)
{
num[j++]=c[a%b];
a/=b;
}
if(t)cout<<"-";
for(int i=j-1;i>=0;i--)cout<<num[i];
cout<<endl;
}
return 0;
}
其中具体的思想很接近用手算时的方法,模拟实现程序。
再贴一个cf上map的思维题
https://codeforces.com/problemset/problem/1296/C
代码
#include <bits/stdc++.h>
using namespace std;
int main() {
#ifdef _DEBUG
freopen("input.txt", "r", stdin);
// freopen("output.txt", "w", stdout);
#endif
int t;
cin >> t;
while (t--)
{
int n;
string s;
cin >> n >> s;
int l = -1, r = n;
map<pair<int, int>, int> vis;
pair<int, int> cur = {0, 0};
vis[cur] = 0;
for (int i = 0; i < n; ++i) {
if (s[i] == 'L') --cur.first;
if (s[i] == 'R') ++cur.first;
if (s[i] == 'U') ++cur.second;
if (s[i] == 'D') --cur.second;
if (vis.count(cur))//如果再次出现当前坐标
{
if (i - vis[cur] + 1 < r - l + 1)
//判断是否为最小区间来决定是否更新数据
{
l = vis[cur];
r = i;
}
}
vis[cur] = i + 1;//开始i是0,所以在下标上加一
}
if (l == -1)
{
cout << -1 << endl;
}
else
{
cout << l + 1 << " " << r + 1 << endl;
}
}
return 0;
}
该题涉及到一个pair和map的组合使用,map<pair<int,int>,int>,宏观来看类似于一个坐标,每个坐标对应一个值
顺便贴一下map的用法
https://www.geeksforgeeks.org/map-associative-containers-the-c-standard-template-library-stl/
再补充一些小的基础知识
2.基础排序
众所周知,排序有许多方法,
如经典の快速排序,蕴含分治思想的归并排序,还有暴力破解の冒泡排序
快排模板
#include<iostream>
using namespace std;
const int N=100010;
int n,a[N];
void quick_sort(int l,int r,int a[])
{
if(l>=r)return;
int mid=a[l+r>>1];
int i=l-1,j=r+1;
while(i<j)
{
do i++;while(a[i]<mid);
do j--;while(a[j]>mid);
if(i<j)swap(a[i],a[j]);
}
quick_sort(l,j,a);
quick_sort(j+1,r,a);
}
signed main()
{
scanf("%d",&n);
for(int i=0;i<n;i++)scanf("%d",&a[i]);
quick_sort(0,n-1,a);
for(int i=0;i<n;i++)printf("%d ",a[i]);
return 0;
}
归并排序
#include<iostream>
using namespace std;
const int N=100010;
int a[N],t[N],n;
void divide_sort(int l,int r,int a[])
{
if(l>=r)return;
int mid=l+r>>1;
divide_sort(l,mid,a),divide_sort(mid+1,r,a);
int i=l,j=mid+1,k=0;
while(i<=mid&&j<=r)
{
if(a[i]<a[j])t[k++]=a[i++];
else t[k++]=a[j++];
}
while(i<=mid)t[k++]=a[i++];
while(j<=r)t[k++]=a[j++];
for(int i=l,k=0;i<=r;i++,k++)a[i]=t[k];
}
signed main()
{
scanf("%d",&n);
for(int i=0;i<n;i++)scanf("%d",&a[i]);
divide_sort(0,n-1,a);
for(int i=0;i<n;i++)
printf("%d ",a[i]);
return 0;
}
相关练习
https://www.acwing.com/activity/content/problem/content/820/
https://www.acwing.com/problem/content/790/
冒泡就不提了,感觉基本用不到,时间复杂度是O(n*2)
真正在写代码的时候用的最多的还是sort函数
基本用法的介绍https://cplusplus.com/reference/algorithm/sort/
又快,时间复杂度还和快排以及归并一样都是O(nlogn)简直泰库辣
除此之外,我用的比较多的就是结构体排序或者类结构体排序
不喜欢struct的也可以用pair来代替
一些例题
https://codeforces.com/problemset/problem/1833/A
#include<iostream>
#include<set>
#include<cstring>
using namespace std;
signed main()
{
int T; cin >> T;
while (T--)
{
set<string>se;
int n; cin >> n;
string s,s1; cin >> s;
for (int i = 1; i < n; i++)
{
s1 = s.substr(i-1, 2);
se.insert(s1);
}
cout << se.size()<<endl;
}
return 0;
}
把这道题放上来,是因为涉及到一个substr函数的运用
再给一道很酷的题
https://www.luogu.com.cn/problem/P1012
#include<iostream>
#include<algorithm>
using namespace std;
string s[10010];
bool cmp(string x, string y)
{
return x + y > y + x;
}
signed main()
{
int n; scanf("%d", &n);
for (int i = 0; i < n; i++)cin >> s[i];
sort(s, s + n, cmp);
string s1;
for (int i = 0; i < n; i++)
{
s1 += s[i];
}
cout << s1;
return 0;
}
这个cmp函数的用法真的泰库辣
(以上内容纯属猜忌瞎说,如有错误,欢迎指正)