题解,答辩总结

at B-Points on Plane
思路:想到一个很好的思路,在菱形中假设取正方形估算出大概值,开方后此值一定<=期待值,
 于是,逐步++构造更大的正方形逼近囊括期待的菱形即可
 

​
#include
#include
#include
using namespace std;
typedef long long ll;
int main() {
    int t;
    cin >> t;
    while (t--) {
        ll n;
        cin >> n;
        if (n == 1) {
            cout << 0 <<'\n';
            continue;
        }
        if (n <= 4) {
            cout << 1 <<'\n';
            continue;
        }
        ll ans = (ll)sqrt(n);
        while (ans * ans < n)ans++;      //处理ll直接开方的精度丢失问题
        cout << ans - 1 << endl;
    }
    return 0;
}

​

T - Open the Lock
思路:双向bfs执行+1操作和交换操作,从前往后有交叉或从后往前有交叉return
 

#include
#include
#include
using namespace std;
const int maxn = 1e4 + 10;
struct node{
    int a[4];
    int step;
}s, e;
int vis[maxn];//标记当前状态是否有走过(从前往后走为1,从后往前走为2,没有走过为0)
int mp[maxn];//标记走到当前状态的步数
int get_num(int c[])
{
    int n = 0;
    for (int i = 0; i < 4; i++){
        n *= 10;
        n += c[i];
    }
    return n;
}
int bfs()
{
    memset(vis, 0, sizeof(vis));
    memset(mp, 0, sizeof(mp));
    queuep, q;
    int tmp;
    tmp = get_num(s.a);
    vis[tmp] = 1;
    tmp = get_num(e.a);
    vis[tmp] = 2;
    node u, v;
    p.push(s);
    q.push(e);
    while (!q.empty() || !p.empty())
    {
        if (!p.empty()){
            u = p.front();
            p.pop();
            for (int i = 0; i < 4; i++){    //+1操作
                v = u;
                v.a[i] = u.a[i] + 1;
                if (v.a[i] == 10)
                    v.a[i] = 1;
                tmp = get_num(v.a);
                if (vis[tmp] == 0)//从前往后没有走过
                {
                    v.step = u.step + 1;
                    mp[tmp] = v.step;//标记走到当前状态的步数
                    vis[tmp] = 1;
                    p.push(v);
                }
                else if (vis[tmp] == 2)//从前往后与从后往前有交叉
                    return u.step + mp[tmp] + 1;
                v.a[i] = u.a[i] - 1;       //-1操作
                if (v.a[i] == 0)
                    v.a[i] = 9;
                tmp = get_num(v.a);
                if (vis[tmp] == 0)
                {
                    v.step = u.step + 1;
                    mp[tmp] = v.step;
                    vis[tmp] = 1;
                    p.push(v);
                }
                else if (vis[tmp] == 2)
                    return u.step + mp[tmp] + 1;
            }
            for (int i = 0; i < 3; i++)//交换
            {
                v = u;
                int k = v.a[i];            //交换
                v.a[i] = v.a[i + 1];
                v.a[i + 1] = k;
                tmp = get_num(v.a);
                if (vis[tmp] == 0)
                {
                    v.step = u.step + 1;
                    mp[tmp] = v.step;
                    vis[tmp] = 1;
                    p.push(v);
                }
                else if (vis[tmp] == 2)
                    return u.step + mp[tmp] + 1;
            }

        }
        if (!q.empty())
        {
            u = q.front();
            q.pop();
            for (int i = 0; i < 4; i++)
            {
                v = u;
                v.a[i] = u.a[i] + 1;
                if (v.a[i] == 10)
                    v.a[i] = 1;
                tmp = get_num(v.a);
                if (vis[tmp] == 0)
                {
                    v.step = u.step + 1;
                    mp[tmp] = v.step;
                    vis[tmp] = 2;
                    q.push(v);
                }
                else if (vis[tmp] == 1)//从后往前与从前往后有交叉
                    return u.step + mp[tmp] + 1;

                v.a[i] = u.a[i] - 1;
                if (v.a[i] == 0)
                    v.a[i] = 9;
                tmp = get_num(v.a);
                if (vis[tmp] == 0){
                    v.step = u.step + 1;
                    mp[tmp] = v.step;
                    vis[tmp] = 2;
                    q.push(v);
                }
                else if (vis[tmp] == 1)
                    return u.step + mp[tmp] + 1;
            }
            for (int i = 0; i < 3; i++){
                v = u;
                int k = v.a[i];
                v.a[i] = v.a[i + 1];
                v.a[i + 1] = k;
                tmp = get_num(v.a);
                if (vis[tmp] == 0){
                    v.step = u.step + 1;
                    mp[tmp] = v.step;
                    vis[tmp] = 2;
                    q.push(v);
                }
                else if (vis[tmp] == 1)
                    return u.step + mp[tmp] + 1;
            }
        }
    }
}
int main()
{
    int t;
    cin >> t;
    while (t--){
        string s1, s2;
        cin >> s1 >> s2;
        for (int i = 0; i < 4; i++)
            s.a[i] = s1[i] - '0';
        for (int i = 0; i < 4; i++)
            e.a[i] = s2[i] - '0';
        s.step = 0;
        e.step = 0;
        cout<

H-Eight

 整体思路:需要引入新知识点康托展开,A*算法,曼哈顿距离

康拓展开+A*算法(h:曼哈顿距离估价,g:步数)+优先队列+利用逆序数判断是否有解

​
#include
#include
#include
#include
using namespace std;
struct Node{
    int mp[3][3];
    int x, y;
    int h, g;  //h:距目标还有多远  g:走了多少步 
    int hash;    //此时数码序列在整个全排列中的次序,即hash值 
    bool operator < (const Node A)const {  //重载 < 
        if (A.h != h) return A.h < h;
        else return A.g < g;
    }
    bool check(){      //检查交换是否合法 
        if (x >= 0 && x < 3 && y >= 0 && y < 3)
            return true;
        return false;
    }
}u, v;
int vis[362880+10];//记录交换方式 
int pre[362880+10];//记录前一个数码序列的hash值 
int dir[4][2] = { {0,1},{0,-1},{1,0},{-1,0} };
int f[] = { 1,1,2,6,24,120,720,5040,40320,362880 };
int get_hash(Node temp)//康托展开,计算数列的hash值 
{
    int a[9], k = 0, count = 0;
    for (int i = 0; i < 3; i++)
        for (int j = 0; j < 3; j++)
            a[k++] = temp.mp[i][j];    //化为一行
    for (int i = 0; i < 9; i++){
        int sum = 0;
        for (int j = i + 1; j < 9; j++)
            if (a[i] > a[j]) sum++;
        count += sum * f[9 - i - 1];
    }
    return count + 1;
}
int get_h(Node temp)        //估价函数 ,每个数字到目标位置的距离,曼哈顿距离
{
    int count = 0;
    for (int i = 0; i < 3; i++)
        for (int j = 0; j < 3; j++)
            if (temp.mp[i][j])
                count += abs(i - (temp.mp[i][j] - 1) / 3) + abs(j - (temp.mp[i][j] - 1) % 3);
    return count;
}
bool judge(Node temp)        //判断是否有解 
{
    int a[9], k = 0, count = 0;
    for (int i = 0; i < 3; i++)
        for (int j = 0; j < 3; j++)
            a[k++] = temp.mp[i][j];

    for (int i = 0; i < 9; i++)
        for (int j = i + 1; j < 9; j++)
            if (a[i] && a[j] && a[i] > a[j])
                count++;
    return count & 1;
}
void print()
{
    string str;
    str.clear();
    int start = 46234;
    while (pre[start] != -1){
        if (vis[start] == 0) str += 'r';
        else if (vis[start] == 1) str += 'l';
        else if (vis[start] == 2) str += 'd';
        else if (vis[start] == 3) str += 'u';
        start = pre[start];
    }
    for (int i = str.size() - 1; i >= 0; i--)     //反向输出
        cout << str[i];
    cout << '\n';
}
void bfs()
{
    memset(vis, -1, sizeof(vis));
    memset(pre, -1, sizeof(pre));
    priority_queue q;              //优先队列
    q.push(u);
    vis[u.hash] = -2;
    while (!q.empty()){
        u = q.top();
        q.pop();
        for (int i = 0; i < 4; i++){
            v = u;
            v.x += dir[i][0];
            v.y += dir[i][1];
            if (v.check()){
                swap(v.mp[v.x][v.y], v.mp[u.x][u.y]);
                v.hash = get_hash(v);
                if (vis[v.hash] == -1){
                    v.h = get_h(v);
                    v.g++;
                    vis[v.hash] = i;                    //步骤记录
                    pre[v.hash] = u.hash;
                    q.push(v);
                }
            }
            if (v.hash == 46234){
                print(); return;
            }
        }
    }
}
int main()
{
    char ch[50];
    while (cin >> ch[0]){
        for (int i = 1; i < 9; i++)
            cin >> ch[i];
        for (int i = 0; i < 3; i++)    //行
            for (int j = 0; j < 3; j++)        //列
                if (ch[i * 3 + j] == 'x') {
                    u.mp[i][j] = 0, u.x = i, u.y = j; u.g = 0;
                }
                else
                    u.mp[i][j] = ch[i * 3 + j] - '0';
        u.h = get_h(u), u.hash = get_hash(u);
        if (u.hash == 46234){           //处理一开始就是期待值的情况
            cout << '\n';
            continue;
        }
        if (!judge(u))
            bfs();
        else cout << "unsolvable" << endl;
    }
}

​

答辩总结

1.没有落实到书上
2.对知识点没有理解透彻
3.亲自上手敲代码的经验太少
4.上台表现太过紧张
5.花Java学习时间太少
 

你可能感兴趣的:(c++,算法,数据结构)