- 设计一个公平的洗牌算法
- 写一个简单的死锁程序:
#include <iostream>
#include <thread>
#include <mutex>
using namespace std;
int data = 1;
mutex mut1,mut2;
void fun2() {
data = 20;
mut1.lock(); //第二次申请对mut1上锁,失败
cout << data << endl;
mut1.unlock();
}
void fun1() {
mut1.lock(); //第一次对mut1上锁
data = 30;
fun2();
cout << data << endl;
mut1.unlock();
}
int main() {
cout << "I'm here!" << endl;
thread thr1(fun1);
thr1.join();
cout<<"I'm here now!"<<endl;
return 0;
}
- 写一个类似 printf 的可以接受任意类型,任意个数的打印函数
#include <iostream>
void show_list() { } //递归的终止条件,args 为 0
template <typename T> //单独处理最后一个参数,换行而不是 ,
void show_list(const T &value) {
std::cout << value << std::endl;
}
template <typename T, typename... Args>
void show_list(const T &value, const Args &...args) {
std::cout << value << ",";
show_list(args...);
}
int main() {
int n = 19;
std::string s = "kjfdh";
double f = 1.11123;
show_list(n, f, s);
return 0;
}
- 问:用预处理指令计算一年有多少秒
#include <iostream>
#define Year_Second (365UL*24*3600UL)
using namespace std;
// 此方法不会影响运行性能
// 宏不仅仅是字符替换而已
// 一般的编译器会把能计算出来的宏(无参数或参数为常量)计算为最后的结果
int main() {
cout << Year_Second << endl;
return 0;
}
- 问题:判断给定的 ip 是否合法
#include <iostream>
#include <regex>
using namespace std;
bool isValid(const string &ip) {
string ts;
bool ans = true;
regex add("[0-9]|[1-9][0-9]|[1-2][0-4][0-9]|25[0-5]");
for(int i =0; i < ip.length(); i++) {
if(ip[i]!='.') ts+=ip[i];
else {
ans = regex_match(ts, add);
if(!ans) return false;
cout << "ts = " << ts << " : " << ans << endl;
ts = "";
}
}
return ans;
}
int main() {
string ip;
while(cin >> ip) {
regex address("[0-9]+.[0-9]+.[0-9]+.[0-9]+");
if(!regex_match(ip, address)) {
cout << "false" << endl;
continue;
} else {
string tip = ip;
tip += "."; // 为了方便 isValid 函数统一处理,可以一依据'.'提取出每个数字段
cout << isValid(tip) << endl;
}
}
return 0;
}
- 问题: 给定 N 个数, 判断数组中是否包含重复数字
#include<iostream>
#include<ctime>
using namespace std;
//判断数组中是否包含重复数字
bool isDuplicate(int val[], int n) {
for(int i=0;i<n;i++) {
if(val[i]!=i) {
if(val[i] != val[val[i]])
swap(val[i],val[val[i]]);
else
return true;
}
}
return false;
}
int main() {
int n;
while(cin >> n) {
int val[n];
srand((unsigned)time(NULL));
cout<<"init data:"<<endl;
for(int i=0;i<n;i++) {
int tmp=rand()%n;
val[i]=tmp;
cout<<tmp<<" ";
}
cout<<endl;
bool flag=isDuplicate(val, n);
if(flag)
cout << "has duplicate elem" << endl;
else
cout << "no duplicate elem" << endl;
}
return 0;
}
- 问题: 素数筛选法:给定 N , 输出 [ 1, N ] 的所有素数
#include <iostream>
#include <cmath>
#define Max_n 100001
using namespace std;
bool isPrime[Max_n];
int main() {
// 先把所有奇数小标的标为 true;
// 把所有偶数小标的标为 false;
for(int i = 0; i < Max_n; i++) {
if(i%2) isPrime[i] = true;
else isPrime[i] = false;
}
isPrime[2] = true;
int n_sqrt = floor(sqrt(double(Max_n)));
cout << n_sqrt << endl;
for(int i = 3; i <= n_sqrt; i+=2) {
if(isPrime[i]) {
for(int j = 2*i; j <= Max_n; j+=i) {
isPrime[j] = false;
}
}
}
int n;
int counts = 0;
while(cin >> n) {
for(int i = 0; i < n; i++) {
if(isPrime[i]) {
counts++;
cout << i << " ";
}
}
cout << "counts = " << counts << endl;
cout << endl;
}
return 0;
}
- 问题:输出一个单链表的倒数第 k 个节点
- 细节:尾部插入法, 头节点,快慢指针
#include <iostream>
using namespace std;
struct ListNode {
int m_nKey;
ListNode* m_pNext;
};
ListNode* FindKthToTail(ListNode* pListHead, unsigned int k) {
ListNode *pFast, *pLow;
pFast = pLow = pListHead;
for(int i = 0; i < k; i++) {
pFast = pFast->m_pNext;
}
while(pFast) {
pFast = pFast->m_pNext;
pLow = pLow->m_pNext;
}
return pLow;
}
int main() {
int k, n;
while(cin >> n && n) {
ListNode *pHead = new ListNode;
pHead->m_nKey = n;
pHead->m_pNext = NULL;
ListNode *pTail = pHead;
for(int i = 0; i < n; i++) {
ListNode *tmpNode = new ListNode;
cin >> tmpNode->m_nKey;
tmpNode->m_pNext = NULL;
pTail->m_pNext = tmpNode;
pTail = tmpNode;
}
cin >> k;
ListNode *p = pHead->m_pNext;
while(p) {
cout << p->m_nKey << " ";
p = p->m_pNext;
}
cout << endl;
p = pHead->m_pNext;
if(k > n) {
return 0;
} else {
ListNode *ptr = new ListNode;
ptr = FindKthToTail(p, k);
if(!ptr)
cout << ptr->m_nKey << endl;
}
}
return 0;
}
- 问:走出迷宫,从左上角开始,右下角离开,输出最短路径
#include <iostream>
#include <queue>
#define max_s 10
using namespace std;
typedef struct points {
int x;
int y;
}Point;
int n, m;
Point pre[max_s][max_s]; //记录路径
int maze[max_s][max_s]; //迷宫信息
bool vis[max_s][max_s]; //是否走过
int dir[4][2] = {{1,0},{-1,0},{0,1},{0,-1}};
//打印路径
void myPrint(Point cur) {
if(cur.x == 1 && cur.y == 1) {
cout << "(0,0)" << endl;
return ;
}
myPrint(pre[cur.x][cur.y]);
cout << "(" << cur.x-1 << "," << cur.y-1 << ")" << endl;
}
// maze[1][1] 到 maze[n][m] 的最短路径
void bfs(int x, int y) {
//初始化队列
queue<Point> que;
Point sPoint;
sPoint.x = x;
sPoint.y = y;
//start_Point & now_Point,并把起点压入队列
que.push(sPoint);
vis[x][y] = true; //起点被走过了
while(!que.empty()) {
Point nPoint = que.front();
que.pop();
if(nPoint.x == n && nPoint.y == m) {
myPrint(nPoint);
break;
}
// 探索四个方向
for(int i = 0; i < 4; i++) {
int nx = nPoint.x + dir[i][0];
int ny = nPoint.y + dir[i][1];
//检查是否越过边界
if(nx>=1 && nx<=n && ny>=1 && ny<=m
&& maze[nx][ny]==0 && !vis[nx][ny]) {
vis[nx][ny] = true;
Point newPoint;
newPoint.x = nx;
newPoint.y = ny;
que.push(newPoint);
pre[newPoint.x][newPoint.y] = nPoint; //记录前驱节点
}
}
}
}
int main() {
while(cin >> n >> m) {
fill(vis[0], vis[0]+max_s*max_s, false); //初始化都没走过
fill(maze[0], maze[0]+max_s*max_s, 0); //初始化迷宫都为 0
//输入迷宫
for(int i = 1; i <= n; i++)
for(int j = 1; j <= m; j++)
cin >> maze[i][j];
bfs(1, 1);
}
return 0;
}
- 排列组合:求 A(n, m) 和 C(n, m):
#include <iostream>
using namespace std;
long long getA(int n, int m) {
if(n < m) return 0;
long long ans = 1;
while(m--) {
ans *= n;
n--;
}
return ans;
}
long long getC(int n, int m) {
if(n < m) return 0;
return getA(n, m)/getA(m, m);
}
int main() {
int n, m;
while(cin >> n >> m) {
cout << getA(n, n) << endl << getA(m, m) << endl;
cout << getC(n, m) << endl;
}
return 0;
}
- 输出 n 个数中最小的 k 个数,包含交换函数,指针传递,k 趟选择排序
#include <iostream>
using namespace std;
void mySwap(int *a, int *b) {
int tmp = *a;
*a = *b;
*b = tmp;
}
// 核心算法:选择排序
bool GetMinK(unsigned int uiInputNum, int *pInputArray, unsigned int uiK, int *pOutputArray) {
if(uiK < 1 || uiK > uiInputNum)
return false;
for(int i = 0; i < uiK; i++) {
for (int j = i+1; j < uiInputNum; j++) {
if(pInputArray[i] > pInputArray[j]) {
mySwap(&pInputArray[i], &pInputArray[j]);
}
}
pOutputArray[i] = pInputArray[i];
cout << pOutputArray[i] << endl;
}
return true;
}
int main() {
unsigned int n, k;
while(cin >> n >> k) {
int nums[n];
int res[k];
for(int i = 0; i < n; i++) {
cin >> nums[i];
}
bool ans = GetMinK(n, nums, k, res);
if(ans) {
for(int i = 0; i < k - 1; i++)
cout << res[i] << " ";
cout << res[k-1] << endl;
}
}
return 0;
}
问:求二元一次方程:
#include <iostream>
using namespace std;
int main() {
int t;
cin >> t;
while(t--) {
int a[3], b[3], c[3];
cin >> a[1] >> b[1] >> c[1] >> a[2] >> b[2] >> c[2];
int m = a[1]*b[2]-b[1]*a[2];
if(m==0) {
cout << "Unknown" << endl;
} else {
int p1 = c[1]*b[2]-c[2]*b[1];
int p2 = a[1]*c[2]-c[1]*a[2];
double x = (p1*1.0)/(m*1.0);
double y = (p2*1.0)/(m*1.0);
cout << x << " " << y << endl;
}
}
return 0;
}
问:求最小连续子序列和:
#include <iostream>
#include <algorithm>
using namespace std;
int main() {
int n;
while(cin >> n) {
int nums[n];
int dp[n+1];
fill(dp, dp+n+1, 0x3f3f3f);
for(int i = 0; i < n; i++)
cin >> nums[i];
for(int i = 1; i < n; i++) {
dp[i] = min(nums[i], dp[i-1]+nums[i]);
}
int ans = *min_element(dp, dp+n);
cout << ans << endl;
}
return 0;
}