NOIP2015 recovery disk (there are pot)

NOIP2015 Replay

D1T1 P2615 magical magic square

Direct simulation, needless to say

NOIP2017 preliminariesIt zhenti like

#include<cstdio>

const int maxn = 45;
int a[maxn][maxn];
int n, x, y;//x means heng, y means shu
void print()
{
    for(int i = 1; i <= n; i++)
    {
        for(int j = 1; j <= n; j++)
        {
            printf("%d", a[i][j]);
            if(j != n) printf(" ");
        }
        printf("\n");
    }
}
int main()
{
    //freopen("in.txt", "r", stdin);
    scanf("%d", &n);
    a[x = 1][y = (n + 1) / 2] = 1;
    for(int i = 2; i <= n * n; i++)
    {
        if(x == 1 && y != n) x = n, y++;
        else if(y == n && x != 1) y = 1, x--;
        else if(x == 1 && y == n) x++;
        else
        {
            if(x - 1 >= 1 && y + 1 <= n && a[x - 1][y + 1] == 0) x--, y++;
            else x++;
        }
        a[x][y] = i;
        //print();
        //printf("\n");
    }
    print();
    return 0;
}

D1T2 P2661 messaging

At first I did not know OI learn graph theory, just want to use STL inside the collection processing solutions, but has been T. Or too naive ah!

To everyone abstracted as a point of telling someone a birthday is not even a directed edge, obviously the answer is inside the smallest ring.

I saw three approaches:

  1. Cannon fight mosquitoes, tarjan for the Minimum Unicom strong component.
  2. Weighted iced tea Kyi find the smallest ring. Each recording from one point to their ancestors, ancestors even if two different points up, if the same ancestor that both of them away plus 1. The answer to the minimum value.
  3. Topological sorting (played by himself). Because the 0 degree must not ring, so follow topological sort of practice has been deleted and can not be deleted when the last remaining true to the ring. And because each person has only one side even out, so everyone just in a ring, directly dfs find the smallest ring ok.

Gives the second and third code (copied from the pyrolysis zone luoguP2661 title):

#include<cstdio>
#include<iostream>
using namespace std;
int f[200002],d[200002],n,minn,last;   //f保存祖先节点,d保存到其祖先节点的路径长。 
int fa(int x)
{
    if (f[x]!=x)                       //查找时沿途更新祖先节点和路径长。 
    {
        int last=f[x];                 //记录父节点(会在递归中被更新)。 
        f[x]=fa(f[x]);                 //更新祖先节点。 
        d[x]+=d[last];                 //更新路径长(原来连在父节点上)。 
    }
    return f[x];
}
void check(int a,int b)
{
    int x=fa(a),y=fa(b);               //查找祖先节点。 
    if (x!=y) {f[x]=y; d[a]=d[b]+1;}   //若不相连,则连接两点,更新父节点和路径长。 
    else minn=min(minn,d[a]+d[b]+1);   //若已连接,则更新最小环长度。 
    return;
}
int main()
{
    int i,t;
    scanf("%d",&n);
    for (i=1;i<=n;i++) f[i]=i;         //祖先节点初始化为自己,路径长为0。 
    minn=0x7777777;
    for (i=1;i<=n;i++)
    {
        scanf("%d",&t);
        check(i,t);                    //检查当前两点是否已有边相连接。 
    }
    printf("%d",minn);
    return 0;
}
#include <iostream>
#include <cstdio>
#include <cstring>
#include <string>
#include <cmath>
#include <algorithm>
#include <queue>
using namespace std;
int n,t[200050],d[200050],ans=1000000000,r[200050];
void read(int& x){
    x=0;
    int y=1;
    char ch=getchar();
    while (ch<'0'||ch>'9'){
        if (ch=='-') y=-1;
        ch=getchar();
    }
    while (ch>='0'&&ch<='9'){
        x=x*10+ch-'0';
        ch=getchar();
    }
    x=x*y;
}
void dfs(int ti,int s,int l){
    if (ti==s&&l){                                //如果回到开始说明连成了环 
        ans=min(ans,l);
        return;
    }
    if (!d[t[ti]]) {
        d[t[ti]]=1;                                //标记 
        dfs(t[ti],s,l+1);
    }
}
void rmove(int ti){                                //删除ti 
    d[ti]=-1;                                    //标记 
    r[t[ti]]--;                                    //ti的下一个人的入度减一 
    if (!r[t[ti]]&&d[t[ti]]!=-1) rmove(t[ti]);
}
int main(){
    memset(d,0,sizeof(d));
    memset(r,0,sizeof(r));                        //r[i]为第 i 个人的入度 
    int i;
    read(n);
    for (i=1;i<=n;i++){
        read(t[i]);
        r[t[i]]++;
    }
    for (i=1;i<=n;i++){
        if (!r[i]&&d[i]!=-1) rmove(i);            //如果 i 的入度为 0 且还未被删除,则删除i 
    }
    for (i=1;i<=n;i++){
        if (!d[i]){                                //如果i还未搜过且未被删除,则从i开始搜索 
            //cout<<i<<' ';
            dfs(i,i,0);
        }
    }
    printf("%d",ans);
    return 0;
}

D1T3 P2668 Landlords

Search large simulation of large cancer problem! Landlords will not finish the

This question is a total of some way to these types of cards (or else can not do it):

Store cards do not need color, only a few number of cards required. For convenience you can set the standard for the corresponding Chin cards, because of the presence of A and 2 very troublesome.

The idea is correct pieces of big violence, enumerations with or without energy band, and the rest scattered on the cards to play a single or pair. The overall framework put backtracking.

When fried king can put the final pair or single treatment, not previously dealt with.

First considered in turn three straight, single and double straight straight, the longest of violence find legitimate straight, directly off.

Next, consider the four belts and three zones. Four-zone as an example, let's find four fried, and then divided into three parts, one out of four with a pair and four with two pairs, the other part of the four belts I and IV with two, and finally do not forget the bomb. Three zones is the same reason, you can single out three cards.

In fact, the only remaining single, double and king pair only. We put two king as the same card, like other cards out of the ordinary on the line.

Finally when the remaining cards in a state of 0, if it is smaller than the current answers included in the answer.

Of course, you can mess of an optimal pruning.

Plus much more difficult than this!

Code:

#include<cstdio>
#include<cstring>
#include<algorithm>
const int maxn = 25;
const int order[15] = {0, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 1, 2, 0};
const int INF = 0x3f3f3f3f;
int card[maxn];
int n, ans;
int read()
{
    int ans = 0, s = 1;
    char ch = getchar();
    while(ch > '9' || ch < '0'){ if(ch == '-') s = -1; ch = getchar(); }
    while(ch >= '0' && ch <= '9') ans = ans * 10 + ch - '0', ch = getchar();
    return s *ans;
}
void dfs(int left, int res)
{
    if(res >= ans) return;
    if(left == 0)
    {
        ans = std::min(ans, res);
        return;
    }
    for(int i = 1; i <= 11; i++)// san shun zi
    {
        if(card[order[i]] >= 3)
        {
            int p;
            for(p = i + 1; p <= 12; p++)
            {
                if(card[order[p]] < 3) break;
            }
            p--;
            if(p - i + 1 >= 2)
            {
                for(int j = i; j <= p; j++) card[order[j]] -= 3;
                dfs(left - (p - i + 1) * 3, res + 1);
                for(int j = i; j <= p; j++) card[order[j]] += 3;
            }
        }
    }
    for(int i = 1; i <= 10; i++)// shuang shun zi
    {
        if(card[order[i]] >= 2)
        {
            int p;
            for(p = i + 1; p <= 12; p++)
            {
                if(card[order[p]] < 2) break;
            }
            p--;
            if(p - i + 1 >= 3)
            {
                for(int j = i; j <= p; j++) card[order[j]] -= 2;
                dfs(left - (p - i + 1) * 2, res + 1);
                for(int j = i; j <= p; j++) card[order[j]] += 2;
            }
        }
    }
    for(int i = 1; i <= 8; i++)// dan shun zi
    {
        if(card[order[i]] >= 1)
        {
            int p;
            for(p = i + 1; p <= 12; p++)
            {
                if(card[order[p]] < 1) break;
            }
            p--;
            if(p - i + 1 >= 5)
            {
                for(int j = i; j <= p; j++) card[order[j]]--;
                dfs(left - (p - i + 1), res + 1);
                for(int j = i; j <= p; j++) card[order[j]]++;
            }
        }
    }
    for(int i = 1; i <= 13; i++)// si dai
    {
        if(card[order[i]] >= 4)
        {
            card[order[i]] -= 4;
            for(int j = 1; j <= 14; j++)
            {
                if(card[order[j]] >= 2)
                {
                    card[order[j]] -= 2;
                    for(int k = j; k <= 14; k++)
                    {
                        if(card[order[k]] >= 2)
                        {
                            card[order[k]] -= 2;
                            dfs(left - 8, res + 1);// si dai liang dui
                            card[order[k]] += 2;
                        }
                    }
                    dfs(left - 6, res + 1);// si dai yi dui
                    card[order[j]] += 2;
                }
            }
            for(int j = 1; j <= 14; j++)
            {
                if(card[order[j]] >= 1)
                {
                    card[order[j]]--;
                    for(int k = j; k <= 14; k++)
                    {
                        if(card[order[k]] >= 1)
                        {
                            card[order[k]]--;
                            dfs(left - 6, res + 1);// si dai liang zhang
                            card[order[k]]++;
                        }
                    }
                    dfs(left - 5, res + 1);// si dai yi zhang
                    card[order[j]]++;
                }
            }
            dfs(left - 4, res + 1);// zha dan
            card[order[i]] += 4;
        }
    }
    for(int i = 1; i <= 13; i++)// san dai 
    {
        if(card[order[i]] >= 3)
        {
            card[order[i]] -= 3;
            for(int j = 1; j <= 14; j++)
            {
                if(card[order[j]] >= 2)
                {
                    card[order[j]] -= 2;
                    dfs(left - 5, res + 1);// san dai yi dui
                    card[order[j]] += 2;
                }
                if(card[order[j]] >= 1)
                {
                    card[order[j]]--;
                    dfs(left - 4, res + 1);// san dai yi zhang
                    card[order[j]]++;
                }
            }
            dfs(left - 3, res + 1);// san zhang pai
            card[order[i]] += 3;
        }
    }
    for(int i = 1; i <= 14; i++)
    {
        if(card[order[i]] == 1 || card[order[i]] == 2)
        {
            left -= card[order[i]];
            res++;
        }
    }
    if(left == 0) ans = std::min(ans, res);
}
int main()
{
    int T = read(); n = read();
    while(T--)
    {
        memset(card, 0, sizeof card);
        ans = INF;
        for(int i = 1; i <= n; i++)
        {
            int x = read(), y = read();
            card[x]++;
        }
        dfs(n, 0);
        printf("%d\n", ans);
    }
    return 0;
}

D2T1 P2678 jump stone

Getting classic dichotomy answer questions.

Subject to monotonicity found: When the shortest distance is smaller jump, the less need Bandiao stone, and when the shortest distance larger jump, the more need Bandiao stones.

So just right to remove most of the \ (M \) when a rock, jump shortest distance maximum.

So the answer is to determine the binary thinking, start thinking about how to determine an answer \ (mid \) eligibility?

check function are generally greedy. When we determine the shortest distance jump, jump less than the shortest distance from the current point in front, it must be removed, otherwise the answer will not be the shortest distance jump. After the next iteration of the need to move out and see how many blocks in total, if less than or equal \ (M \) is legitimate, if not more than legitimate.

Code:

#include<cstdio>
using namespace std;
const int maxn = 50005;
int l, n, m;
int d[maxn];
int ans;
bool check(int x)
{
    int last = 0, cnt = 0;
    for(int i = 1; i <= n; i++)
    {
        if(d[i] - d[last] < x)
        {
            cnt++;
        }
        else last = i;
    }
    if(cnt <= m) return true;
    return false;
}
int main()
{
    scanf("%d%d%d", &l, &n, &m);
    d[0] = 0;
    for(int i = 1; i <= n; i++) scanf("%d", &d[i]);
    d[n + 1] = l;
    int left = 1, right = l;
    while(left <= right)
    {
        int mid = (left + right) >> 1;
        if(check(mid)) ans = mid, left = mid + 1;
        else right = mid - 1;
    }
    printf("%d\n", ans);
    return 0;
}

D2T2 P2679 substring

Pit to be filled

D2T3 P2680 transportation plan

Guess you like

Origin www.cnblogs.com/Garen-Wang/p/11334359.html