分享 求职面试

最近找工作遇到一些面试问题,回答的不是很好。特此回顾一下,做一下总结。
考研面试:static关键字的作用
1.static 关键字可以隐藏全局变量或者函数,被隐藏的全局变量获函数不能被其他文件使用。使用static后可以在不同文件中定义同名函数和同名变量,而不必担心命名冲突。
2.static 关键字可以保持变量内容的持久,static变量存在静态存储区,因此它具备持久性(函数内的局部变量加static关键字后下一次调用仍然能使用它的值)。static修饰的变量默认值为0。

const 和 define的区别
const是在编译过程中使用的,define是在预处理阶段展开的。
const 定义的是变量,而宏定义的是常量,因此const 后面加数据类型,而define 后面不加数据类型。
编译器会对const 进行类型安全检查,而对define 定义的常量只是简单的替换。

RISC和CISC指令集的区别

CISC指令集多 RISC指令集少
CISC指令长度可变 RISC指令集长度固定
CISC可访问指令不加限制 RISC只有LOAD/STORE指令
CISC各种指令执行时间相差大 RISC多数指令在一个时钟周期内完成
CISC指令各种指令使用频率相差较大 RISC多数指令只在一个时钟周期内完成
CISC指令通用寄存器较少 RISC指令通用寄存器多
CISC指令难以用优化编译生成高效的目标代码 RISC采用优化的编译程序,生成代码较为高效
CISC指令大多数用微程序控制 RISC绝大多数为组合逻辑控制

进程和线程的区别
进程由程序段、相关数据段和PCB组成,线程共享其隶属进程的进程映像,仅拥有线程ID、寄存器集合和堆栈等
进程在没有引入线程的操作系统中,进程是独立运行的基本单位。线程是独立运行的基本单位,一个进程可以拥有一个或多个线程。
进程是资源分配和拥有的基本单位,线程自己基本不拥有系统资源,但它可以访问进程所拥有的全部资源。
在没有引入线程的操作系统中,进程是独立调度和分派的基本单位。在引入线程后的操作系统中,线程是独立调度和分派的基本单位。
进程通信:PV操作,共享存储,消息传递,管道通信。线程通信:同一进程的各线程直接读写进程数据段,不同进程的线程之间通信属于进程间通信
系统开销:进程切换时涉及当前CPU环境的保存及新进程CPU环境的设置,开销较大。线程切换时只需保存和设置少量寄存器内容,开销较小。
进程的地址空间互相独立。同一进程的各线程间共享进程的地址空间。




lvky.
6分钟前

题目描述

d17bb2daba3233400b47f461f86640c7_Center.png
查看日历知:1988年1月1日 是 周四

样例

输入 
1998
输出
2 13
3 13
11 13
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cmath>
using namespace std;
int m1[13]={0,31,28,31,30,31,30,31,31,30,31,30,31};
int m2[13]={0,31,29,31,30,31,30,31,31,30,31,30,31};
int main(int argc, char** argv) {
    int y;
    scanf("%d",&y);
    int fd=4;
    int sum=0;
    if((y%4==0&&y%100!=0)||y%400==0){
        for(int i=1;i<13;i++){
            sum=0;
        for(int j=1;j<i;j++){
            sum+=m2[j];
        }
        sum+=12;
        if((sum+fd)%7==5){
            printf("%d 13\n",i);
        }
    }
    }else{
        for(int i=1;i<13;i++){
            sum=0;
        for(int j=1;j<i;j++){
                sum+=m1[j]; 
        }
        sum+=12;
        if((sum+fd)%7==5){
            printf("%d  13\n",i);
        }
    }
    }

        return 0;
}



题目描述

#include <iostream>
#include <cmath>
#include <cstring>
#include <vector>
using namespace std;
const int N=15;
int f[N][N];

int dp(int n)
{
    //memset(f,0,sizeof f);
    if(n==0) return 1;
    vector<int> nums;
    while(n)
    {
        nums.push_back(n%10);
        n=n/10;
    }
    int res=0;
    //last记录上一个数
    int last=0;
    for(int i=nums.size()-1;i>=0;i--)
    {
        int x=nums[i];
        for(int j=0;j<x;j++)
        {
            if(j==4 || (j==2)&&(last==6)) continue;
            res+=f[i+1][j];
        }
        //比如一个数是7621
        //break的时候,已经把76100-76199的给算完了,因为此时x=2,j就能到1
        if(x==4 || last==6 &&x==2) break;
        last=x;
        if(i==0) res++;

    }

    return res;
}

int main()
{
    for(int i=0;i<=9;i++)
    {
        if(i!=4)
        f[1][i]=1;
    }
    for(int i=2;i<N;i++)
    {
        for(int j=0;j<=9;j++)
        {
            if(j==4) continue;
            for(int k=0;k<=9;k++)
            {
                if(k==4 || (j==6)&&(k==2) ) continue;
                f[i][j]+=f[i-1][k];
            }
        }
    }

    int a,b;
    while(cin>>a>>b,a||b)
    {
        cout<<dp(b)-dp(a-1)<<endl;
    }
    return 0;
}



RP
20分钟前

lower_bound()和upper_bound()的写法

#include <bits/stdc++.h>
using namespace std;
const int N = 100010;
int a[N];
int main(){
    int n,q,k;
    cin>>n>>q;
    for(int i=1;i<=n;i++){
        scanf("%d",&a[i]);
    }
    while(q--){
        cin>>k;
        int pos1 = lower_bound(a+1,a+1+n,k)-(a+1);
        int pos2 = upper_bound(a+1,a+1+n,k)-(a+1);
        if(pos1==pos2)//第一个大于等于k如果等于第一个大于k的那么就说明k不存在
        {
            cout<<"-1 -1"<<endl;
        }else{
            cout<<pos1<<" "<<pos2-1<<endl; 
        }
    }
}



ac_please
28分钟前

题目描述

有 N 件物品和一个容量是 V 的背包,背包能承受的最大重量是 M。

每件物品只能用一次。体积是 vi,重量是 mi,价值是 wi。

求解将哪些物品装入背包,可使物品总体积不超过背包容量,总重量不超过背包可承受的最大重量,且价值总和最大。
输出最大价值。

输入格式
第一行两个整数,N,V,M,用空格隔开,分别表示物品件数、背包容积和背包可承受的最大重量。

接下来有 N 行,每行三个整数 vi,mi,wi,用空格隔开,分别表示第 i 件物品的体积、重量和价值。

输出格式
输出一个整数,表示最大价值。

数据范围
0<N≤1000
0<V,M≤100
0<vi,mi≤100
0<wi≤1000

输入样例

4 5 6
1 2 3
2 4 4
3 4 5
4 5 6

输出样例

8

C++ 代码

#include<iostream>
#include<vector>
using namespace std;

const int N = 1010;
int main() {
    int n, m, z;
    cin >> n >> m >> z;
    vector<int> v(N, 0), g(N, 0), w(N, 0);
    vector<vector<int>> dp(N, vector<int>(N, 0));
    for(int i = 0; i < n; ++i) {
        int _v, _m, _w;
        cin >> _v >> _m >> _w;
        v[i] = _v;
        g[i] = _m;
        w[i] = _w;
    }

    for(int i = 0; i < n; ++i) {
        for(int j = m; j >= v[i]; --j) {
            for(int k = z; k >= g[i]; --k) {
                dp[j][k] = max(dp[j][k], dp[j - v[i]][k - g[i]] + w[i]);
            }
        }
    }

    cout << dp[m][z] << endl;
    return 0; 
}



lvky.
28分钟前

题目描述

2020 年春节期间,有一个特殊的日期引起了大家的注意:2020 年 2 月 2日。因为如果将这个日期按 “yyyymmdd” 的格式写成一个 8位数是 20200202,恰好是一个回文数。我们称这样的日期是回文日期。有人表示 20200202 是“千年一遇” 的特殊日子。
对此小明很不认同,因为不到 2 年之后就是下一个回文日期:20211202 即 2021 年 12 月 2日。也有人表示 20200202 并不仅仅是一个回文日期,还是一个 ABABBABA 型的回文日期。
对此小明也不认同,因为大约 100年后就能遇到下一个 ABABBABA 型的回文日期:21211212 即 2121 年 12 月 12日。
算不上“千年一遇”,顶多算“千年两遇”。给定一个 8位数的日期,请你计算该日期之后下一个回文日期和下一个 ABABBABA 型的回文日期各是哪一天。
注意
下一个回文日期和下一个 ABABBABA 型的回文日期可能是同一天。ABABBABA 型的回文日期,需要满足 A≠B。

输入格式
输入包含一个八位整数 N,表示日期。

输出格式
输出两行,每行 1个八位数。
第一行表示下一个回文日期,第二行表示下一个 ABABBABA 型的回文日期。
数据范围
对于所有评测用例,10000101≤N≤89991231,保证 N 是一个合法日期的 8 位数表示。

样例

输入样例:

20200202

输出样例:

20211202
21211212

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cmath>
using namespace std;
int m[13]={0,31,28,31,30,31,30,31,31,30,31,30,31};
bool check(int date){//看看是否合法
    int year=date/10000;
    int month=date%10000/100;
    int day=date%100;

    if(month<=0||month>12) return false;
    if(month==2){
        int leap=(year%4==0&&year%100!=0)||year%400==0;
        if(day>leap+28)  return false;
    }
    if(month!=2&&day>m[month]||day<=0) return false;

    return true;
}
bool checkAB(int date){//判断是都符合ABABBABA型
        int y=date/10000;
        int a=y/100;
        int b=y%100;
        if(a==b&&(a/10!=b%10)){
            return true;
        }
    return false;
}
int main(int argc, char** argv) {
    int year1;
    int miny;
    cin>>year1;
    miny=year1/10000;
    bool flag=true;
    for(int i=miny;i<=9999;i++){
        int y=i;
        int t=i;
        while(t>0){ //根据年份找到对应的回文日期
            y=y*10+t%10;
            t/=10;
    }
        if(check(y)&&y>year1&&flag){
             printf("%d\n",y);
             flag=false;
        }
        if(check(y)&&checkAB(y)&&y>year1){
            printf("%d\n",y);
            break;
        }
    }
        return 0;
}



樊景
28分钟前

题目描述

考虑一个包含 N 个顶点的无向图,编号从 1 到 N,并包含 M 条边。编号为 1 的顶点对应了一个矿藏,可从中提取珍稀的矿石。编号为 N 的顶点对应了一个矿石加工厂。每条边有相应的通行时间 (以时间单位计),以及相应的运载量 (以矿石单位计)。现决定使用一条路径,将从矿藏中提取的矿石运送到加工厂。这条路径应当具有尽可能高的运载量,以便并行运输尽可能多的矿石。路径的运载量等于它的各边的最小运载量。然而,这些矿石很敏感,一旦从矿藏中提取出来,就会在 T 个时间单位之后开始分解,除非在这个时间截止之前到达工厂。因此,所选路径的总通行时间 (各条边的通行时间之和) 应当小于或等于 T。

样例

2
2 1 10
1 2 13 10
4 4 20
1 2 1000 15
2 4 999 6
1 3 100 15
3 4 99 4

13
99

C++ 代码

#include <cstring>
#include <iostream>
#include <algorithm>
#include <queue>
using namespace std;
typedef long long ll;
const int N = 1000010;
ll n,m,time1,dist[N];
ll h[N],e[N],ne[N],idx,w[N],v[N];
bool st[N];
queue<int>q;

void add(int a,int b,int c,int d)
{
    e[idx] = b,ne[idx] = h[a],w[idx] = c,v[idx] = d,h[a] = idx++;
}

ll check(int x)
{
    for(int i = 1;i <= n;i++)
    {
        dist[i] = 1e18;
    }
    memset(st,0,sizeof st);
    while(!q.empty())
    {
        q.pop();
    }
    q.push(1);
    st[1] = true;
    dist[1] = 0;
    while(q.size())
    {
        int t = q.front();
        q.pop();

        st[t] = false;

        for(int i = h[t];i != -1;i = ne[i])
        {
            int j = e[i];
            if(v[i] >= x && dist[j] > dist[t] + w[i])
            {
                dist[j] = dist[t] + w[i];
                if(!st[j])
                {
                    st[j] = true;
                    q.push(j);
                }
            }
        }
    }
    return dist[n];
}

int main()
{
    int t;
    cin >> t;
    while(t--)
    {
        memset(h,-1,sizeof h);
        memset(e,0,sizeof e);
        memset(ne,0,sizeof ne);
        ll top = -1,lower = 1e18;
        cin >> n >> m >> time1;
        while(m--)
        {
            ll a,b,c,d;
            cin >> a >> b >> c >> d;
            add(a,b,d,c),add(b,a,d,c);
            top = max(top,c),lower = min(lower,c);
        }
        ll ans = 0;
        while(lower <= top)
        {
            int mid = lower + top >> 1;
            if(check(mid) == time1)
            {
                ans = mid;
                break;
            }
            else if(check(mid) < time1)
            {
                lower = mid + 1;
            }
            else if(check(mid) > time1)
            {
                top = mid - 1;
            }
        }
        cout << check(99) << endl;
    }
}




ac_please
52分钟前

题目描述

有 N 种物品和一个容量是 V 的背包。

物品一共有三类:

第一类物品只能用1次(01背包);
第二类物品可以用无限次(完全背包);
第三类物品最多只能用 si 次(多重背包);
每种体积是 vi,价值是 wi。

求解将哪些物品装入背包,可使物品体积总和不超过背包容量,且价值总和最大。
输出最大价值。

输入格式
第一行两个整数,N,V,用空格隔开,分别表示物品种数和背包容积。

接下来有 N 行,每行三个整数 vi,wi,si,用空格隔开,分别表示第 i 种物品的体积、价值和数量。

si=−1 表示第 i 种物品只能用1次;
si=0 表示第 i 种物品可以用无限次;
si>0 表示第 i 种物品可以使用 si 次;
输出格式
输出一个整数,表示最大价值。
数据范围
0<N,V≤1000
0<vi,wi≤1000
−1≤si≤1000

输入样例

4 5
1 2 -1
2 4 1
3 4 0
4 5 2

输出样例

8

C++ 代码

#include<iostream>
#include<vector>
using namespace std;
const int N = 20010;

int main() {
    int n, m;
    cin >> n >> m;
    vector<int> dp(N, 0), a(N, 0), b(N, 0), c(N, 0);
    int idx = 1;
    for(int i = 1; i <= n; ++i) {
        int v, w, s;
        cin >> v >> w >> s;
        if(s == 0) { 
            a[idx] = v;
            b[idx] = w;
            c[idx++] = 0;
        } else {
            if(-1 == s) s = 1;
            int k = 1;
            while(k <= s) {
                a[idx] = k * v;
                b[idx] = k * w;
                c[idx++] = 1;
                s -= k;
                k *= 2;
            }
            if(s) {
                a[idx] = s * v;
                b[idx] = s * w;
                c[idx++] = 1;
            }
        }
    }


    for(int i = 1; i < idx; ++i) {
        if(c[i] == 0) {
            for(int j = a[i]; j <= m; ++j) {
                dp[j] = max(dp[j], dp[j - a[i]] + b[i]);
            }
        } else {
            for(int j = m; j >= a[i]; --j) {
                dp[j] = max(dp[j], dp[j - a[i]] + b[i]);
            }
        }
    }

    cout << dp[m] << endl;
    return 0;
}



1.jpg

代码

#include <bits/stdc++.h>
using namespace std;

const int N = 110;
int n;
int g[N][N];

int gauss()
{
    int r = 0, c;
    for (int c = 0; c < n; c++)  //按列进行枚举
    {
        int t = r;  //找到非0行,用t进行存储
        for (int i = r; i < n; i++)
            if (g[i][c])
                t = i;

        if (!g[t][c])
            continue;  //没有找到1,继续下一层循环

        for (int i = c; i <= n; i++)
            swap(g[r][i], g[t][i]);  //把第r行的数与第t行交换。

        for (int i = r + 1; i < n; i++)  //用r行把下面所有行的当前列消成0
            if (g[i][c])
                for (int j = n; j >= c; j--)
                    g[i][j] ^= g[r][j];
        r++;
    }
    if (r < n) {
        for (int i = r; i < n; i++) {
            if (g[i][n])
                return 2;
        }
        return 1;
    }

    for (int i = n - 1; i >= 0; i--) {
        for (int j = i + 1; j < n; j++) {
            g[i][n] ^= g[i][j] * g[j][n];
        }
    }
    return 0;
}
int main()
{
    cin >> n;
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < n + 1; j++) {
            cin >> g[i][j];
        }
    }

    int t = gauss();
    if (t == 0) {
        for (int i = 0; i < n; i++) {
            cout << g[i][n] << endl;
        }
    }
    else if (t == 1)
        puts("Multiple sets of solutions");
    else
        puts("No solution");
    return 0;
}



QAQ_ning
55分钟前
#include <iostream>
#include <cstdio>

using namespace std;

const int N = 1e6 + 10;

int primes[N], cnt;
bool st[N];

void get_primes(int n)
{
    for (int i = 2; i <= n; i ++ )
    {
        if (!st[i]) primes[cnt ++ ] = i;
        for (int j = i + i; j <= n; j += i) st[j] = true;
    }
}

int main()
{
    int x;
    scanf("%d", &x);

    get_primes(x);

    printf("%d\n", cnt);

    return 0;
}