• NOJ AC75记录


    NOJ刷题总结

    +++

    HDU2553

    可能因为样例过多的缘故,刚开始疯狂TLE,后来就需要打表过。

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    
    using namespace std;
    
    const int N = 20;
    char g[N][N];
    bool bias1[N], bias2[N], col[N];
    int sum;
    int storage[10];//打表
    
    void dfs(int u, int n)
    {
        if(u == n)
        {
            sum++;
            return;
        }
        for(int i = 0; i < n; i++ )
            if(!col[i] && !bias1[u + i] & !bias2[n - u + i])
            {
                col[i] = bias1[u + i] = bias2[n - u + i] = true;
                dfs(u + 1, n);
                col[i] = bias1[u + i] = bias2[n - u + i] = false;
            }
    }
    
    int main()
    {
        for(int i = 0; i < 10; i++ )
        {
            sum = 0;
            dfs(0, i + 1);
            storage[i] = sum;
        }
        
        int u;
        while(cin >> u, u)
            cout << storage[u - 1] << endl;   
        return 0;
    }
    
    NOJ1049 飞机航班求最短路
    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    
    using namespace std;
    
    const int N = 25;
    int n, m, v;
    int h[N], e[N], ne[N], q[N], d[N], idx;
    
    void add(int a, int b)
    {
        e[idx] = b, ne[idx] = h[a], h[a] = idx++;
    }
    
    void bfs()
    {
        int hh = 0, tt = 0;
        q[0] = v;
        memset(d, -1, sizeof d);
        
        d[v] = 0;
        while(hh <= tt)
        {
            int t = q[hh++];
            
            for(int i = h[t]; i != -1; i = ne[i])
            {
                int j = e[i];
                if(d[j] == -1)
                {
                    d[j] = d[t] + 1;
                    q[++tt] = j;
                }
            }
        }
        
        for(int i = 0; i < n; i++ )
        {
            if(i == v) continue;
            cout << d[i] << endl;    
        }
    }
    
    int main()
    {
        cin >> n >> m >> v;
        memset(h, -1, sizeof h);
        
        for(int i = 0; i < m; i++ )
        {
            int x, y;
            cin >> x >> y;
            add(x, y);
        }
        
        bfs();
        
        return 0;
    }
    
    NOJ1079 11111...

    既然枚举n的倍数复杂度过高,就反过来枚举不同位数的1

    #include <cstdio>
     
    int main()
    {
    	int n;
    	while(~scanf("%I64d", &n))
    	{
    		int t = 0, ans = 0;
    		while(true)
    		{
    			t = (10 * t + 1) % n;
    			ans++;
    			if(0 == t) break;
    		}
    		printf("%d
    ", ans);
    	}
    	return 0;
    }
    
    #include <iostream>
    #include <algorithm>
    
    using namespace std;
    
    const int N = 100010;
    
    int n, m;
    int h[N], cnt;
    
    void down(int u)
    {
        int t = u;
        if (u * 2 <= cnt && h[u * 2] < h[t]) t = u * 2;
        if (u * 2 + 1 <= cnt && h[u * 2 + 1] < h[t]) t = u * 2 + 1;
        if (u != t)
        {
            swap(h[u], h[t]);
            down(t);
        }
    }
    
    int main()
    {
        scanf("%d%d", &n, &m);
        for (int i = 1; i <= n; i ++ ) scanf("%d", &h[i]);
        cnt = n;
    
        for (int i = n / 2; i; i -- ) down(i);
    
        while (m -- )
        {
            printf("%d ", h[1]);
            h[1] = h[cnt -- ];
            down(1);
        }
    
        puts("");
    
        return 0;
    }
    
    HDU2546 饭卡

    果然自己做出一道dp题是很开心的一件事,(虽然是和模板01背包几乎一样)

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    
    using namespace std;
    
    const int N = 1010;
    int w[N], m, n, g[N][N];
    
    int main()
    {
        while(cin >> m, m)
        {
            for(int i = 1; i <= m; i ++ ) cin >> w[i];
            cin >> n;
            
            if(n < 5)
                cout << n << endl;
            else
            {
            sort(w + 1, w + m + 1);
            
            for(int i = 1; i < m; i ++ )
                for(int j = 0; j <= n - 5; j ++ )
                {
                    g[i][j] = g[i - 1][j];
                    if(j >= w[i]) g[i][j] = max(g[i][j], g[i - 1][j - w[i]] + w[i]);
                }
            
            cout << n - g[m - 1][n - 5] - w[m] << endl;
            }
        }
        return 0;
    }
    
    VIJ1360 八数码

    记录初次使用哈希表

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <unordered_map>
    #include <queue>
    
    using namespace std;
    
    
    int bfs(string s)
    {
        queue<string> q;
        unordered_map<string, int> d;
        
        q.push(s);
        d[s] = 0;
        
        int dx[4] = {-1, 0, 1, 0}, dy[4] = {0, 1, 0, -1};
        string end = "123804765";
        while(q.size())
        {
            auto t = q.front();
            q.pop();
            
            if(t == end) return d[t];
            
            int distence = d[t];
            int k = t.find('0');
            int x = k / 3, y = k % 3;
            for(int i = 0; i < 4; i ++ )
            {
                int a = x + dx[i], b = y + dy[i];
                if(a >= 0 && a < 3 && b >= 0 && b < 3)
                {
                    swap(t[a * 3 + b], t[k]);
                    if(!d.count(t))
                    {
                        d[t] = distence + 1;
                        q.push(t);
                    }
                    swap(t[k], t[a * 3 + b]);
                }
            }
        }
    }
    
    int main()
    {
        string s;
        cin >> s;
        
        cout << bfs(s) << endl;
        
        return 0;
    }
    
    HDU2036 给点坐标求面积

    多边形的面积可以转换为若干个三角形面积的相加,三角形顶点是最后一个点

    三角形的有向面积计算公式:

    s = (x2y3+x3y1+x1y2-x2y1-x3y2-x1y3)/2.0

    #include <iostream>
    
    using namespace std;
    
    int n,x1,y1,x2,y2,x3,y3;  
    double s;  
    
    double getArea(int x1,int y1,int x2,int y2,int x3,int y3)  
    {  
        return (x2*y3+x3*y1+x1*y2-x2*y1-x3*y2-x1*y3)/2.0;  
    }  
    
    int main(){  
        while(~scanf("%d",&n))  
        {  
            if(!n)break;  
            s = 0;  
            scanf("%d %d %d %d %d %d",&x1,&y1,&x2,&y2,&x3,&y3);  
            s += getArea(x1,y1,x2,y2,x3,y3);  
            n = n-3;  
            while(n>0){  
                n--;  
                x2 = x3;  
                y2 = y3;  
                scanf("%d%d",&x3,&y3);  
                s += getArea(x1,y1,x2,y2,x3,y3);  
            }  
            printf("%.1f
    ",s);  
        }  
        return 0;  
    }  
    
    HDU2048 神,上帝与老天爷 (典型错排dp)

    1.假设n个人,前n - 1 个人满足错排,那么第n个人与前面任意一个人互换就可以,一共有(n - 1) * f(n - 1)种情况。

    2.假设n个人,前n - 1不满足错排,然后第n个人与其中一个人互换后满足错排。也就是说前n - 2个人满足错排,因为每个人都可以是之前不满足错排的原因,所以这种情况一共有(n - 1) * f(n - 2)种。

    综上列出状态转移方程f(n) = (n - 1) * (f(n - 1) + f(n - 2))

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    
    using namespace std;
    
    const int N = 30;
    double num[N], sum[N];
    
    void chart()
    {
        num[1] = 0, num[2] = 1;
        sum[1] = 1, sum[2] = 2;
        
        for(int i = 3; i < 25; i ++ )
        {
            num[i] = (i - 1) * (num[i - 1] + num[i - 2]), sum[i] = sum[i - 1] * i;
        }
    }
    
    int main()
    {
        int t;
        cin >> t;
        
        chart();
        
        while(t--)
        {
            int n;
            cin >> n;
            printf("%.2lf%%
    ", (num[n] / sum[n]) * 100.0);
        }
        return 0;
    }
    
    HDU2049 错排
    #include <iostream>
    #include <cstring>
    #include <cstdio>
    #include <algorithm>
    
    using namespace std;
    
    typedef long long LL;
    
    int main()
    {
        int n, m, c;
        LL sum[21], f[21];
        
        sum[0] = 1, sum[1] = 1;
        f[0] = 1, f[1] = 0;
        
        for(int i = 2; i < 21;i ++ )
        {
            sum[i] = sum[i-1] * i;
            f[i] = (i-1)*(f[i-1] + f[i-2]);
        }
        
        cin>>c;
        for(int j = 0; j < c;j ++ )
        {
            cin>>n >> m;
            cout << f[m] * (sum[n] / sum[m] /sum[n-m]) << endl;
        }
        
        return 0;
    }
    
    HDU2045 简单递推

    数据n = 3比较卡,要单独赋值。

    #include <iostream>
    
    using namespace std;
    
    typedef long long LL;
    
    const int N = 55;
    LL dp[N];
    
    void chart()
    {
        dp[1] = 3, dp[2] = 6, dp[3] = 6;
        
        for(int i = 4; i <= 50; i ++ )
            dp[i] = dp[i - 1] + 2 * dp[i - 2];
    }
    
    int main()
    {
        chart();
        
        int n;
        while(cin >> n)
            cout << dp[n] << endl;
        
        return 0;
    }
    
  • 相关阅读:
    微软SQL Server 2005的30项顶尖特性
    UML统一建模语言 类关系
    设计模式 建造者模式
    设计模式 原型模式
    设计模式 简单工厂模式
    设计模式 适配器模式
    设计模式 适配器模式
    设计模式 单例模式
    设计模式 抽象工厂模式
    设计模式 桥接模式
  • 原文地址:https://www.cnblogs.com/scl0725/p/12612430.html
Copyright © 2020-2023  润新知