关于打表

所谓打表,就是将答案全都输出出来,试(pian)输(shu)入(ju),还不懂?另一个解释:
打表就是事先知道一个题的测试数据,然后把这些数据都写上去,比起认真编程解题要简单,只是有时数据会很多。一些考试(NOI等)的测试数据就是所谓的答案。所以有些数据是弄不到的:
对于数据小又容易超时的题,可以采取打表法
打表就是将所有输入情况的答案保存在代码中,输入数据后直接输出就可以了
打表法具有快速,易行(可以写暴力枚举程序)的特点,缺点是代码可能太大,或者情况覆盖不完
对于不会超时,数据规模适合打表,为了简洁你也可以打表(当然,当n^3>=10000时,不建议打表)

难道还么懂么?来,举几个例子你看看:
举个例子:

题目描述
给定N(小于等于8)个点的地图,以及地图上各点的相邻关系,请输出用4种颜色将地图涂色的所有方案数(要求相邻两点不能涂成相同的颜色)

数据中0代表不相邻,1代表相邻

输入

第一行一个整数n,代表地图上有n个点

接下来n行,每行n个整数,每个整数是0或者1。第i行第j列的值代表了第i个点和第j个点之间是相邻的还是不相邻,相邻就是1,不相邻就是0.

我们保证a[i][j] = a[j][i] (a[i,j] = a[j,i])

输出

染色的方案数

样例输入
8
0 0 0 1 0 0 1 0
0 0 0 0 0 1 0 1
0 0 0 0 0 0 1 0
1 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0
0 1 0 0 0 0 0 0
1 0 1 0 0 0 0 0
0 1 0 0 0 0 0 0

样例输出
15552
—————————————————————————
像这道题,正常的做法是这样的:

#include
int map[9][9]={0},clr[9]={0},n,ans=0;
bool check(int k)
{
    for(int i=1;i<=n;i++)
        if(map[i][k]&&k!=i&&clr[i]==clr[k])
            return false;
    return true;
}
void search(int k)
{
    if(k>n)
    {
        ans++;
        return;
    }
    for(clr[k]=1;clr[k]<=4;clr[k]++)
        if(check(k))
            search(k+1);
    clr[k]=0;
}
int main()
{
    int i,j;
    scanf("%d",&n);
    for(i=1;i<=n;i++)
        for(j=1;j<=n;j++)
            scanf("%d",&map[i][j]);
    search(1);
    printf("%d\n",ans);
    return 0;
}

打表(不推荐)是这样的:

#include
using namespace std;
int main()
{
	int k,a[9][9];
	cin>>k;
	for(int i=0;i<k;i++)
	{
		for(int j=0;j<k;j++)
		{
			cin>>a[i][j];
		}
	}
    if(k==8)
    {
    	if(a[0][0]==0 && a[1][0]==0 && a[1][1]==0 && a[3][4]==0 && a[0][4]==0 && a[1][4]==0 && a[2][4]==0 && a[3][4]==0 && a[4][4]==0 && a[5][4]==0 && a[6][4]==0 && a[7][4]==0  )
    	{
    		cout<<15552;
    	}
    	else
		{
			cout<<2208;
    	}
    }
    else if(k==7)
    {
    	cout<<2880;
    }
    else if(k==3)
    {
    	cout<<36;
    }
    else
    {
    	cout<<96;
    }
    return 0;
}

再比如,一些没有数据的题,也可以打标:
「POJ1741」Tree**(暂无数据)**
时间限制: 1 Sec 内存限制: 128 MB
提交: 38 解决: 35
[提交][题解][状态][讨论版]
题目描述
Give a tree with n vertices,each edge has a length(positive integer less than 1001).
Define dist(u,v)=The min distance between node u and v.
Give an integer k,for every pair (u,v) of vertices is called valid if and only if dist(u,v) not exceed k.
Write a program that will count how many pairs which are valid for a given tree.
输入
The input contains several test cases. The first line of each test case contains two integers n, k. (n<=10000) The following n-1 lines each contains three integers u,v,l, which means there is an edge between node u and v of length l.
The last test case is followed by two zeros.
输出
For each test case output the answer on a single line.
样例输入
5 4
1 2 3
1 3 1
1 4 2
3 5 1
0 0
样例输出
8
提示

给一颗n个节点的树,每条边上有一个距离v。定义d(u,v)为u到v的最小距离。给定k值,求有多少点对(u,v)使u到v的距离小于等于k。
正常思路是这样的:

#include
#define MAXN 10002
#define INF 0x7f7f7f7f
using namespace std;
int head[MAXN+5],sim[MAXN+5],mxson[MAXN+5],vis[MAXN+5],MX,root,dis[MAXN+5],summar,n,k,cnt,s;
long long ans;
struct node
{
    int to,nxt,len;
}t[2*MAXN+5];
void add_edge(int u,int v,int l)
{
    cnt++;
    t[cnt].to=v;
    t[cnt].nxt=head[u];
    t[cnt].len=l;
    head[u]=cnt;
    return;
}
void getroot(int u,int fa)
{
    sim[u]=1;
    mxson[u]=0;
    for(int i=head[u];i;i=t[i].nxt)
    {
        int v=t[i].to;
        if(v==fa||vis[v])
            continue;
        getroot(v,u);
        sim[u]=sim[u]+sim[v];
        mxson[u]=max(sim[v],mxson[u]);
    }
    mxson[u]=max(mxson[u],s-sim[u]);
    if(mxson[u]<MX)
    {
        root=u;         
        MX=mxson[u];
    }
}
void getdis(int u,int fa,int dist)
{
    dis[++summar]=dist;
    for(int i=head[u];i;i=t[i].nxt)
    {
        int v=t[i].to;
        if(vis[v]||v==fa)
            continue;
        getdis(v,u,dist+t[i].len);
    }
    return;
}
int consolate(int sta,int len0)
{
    summar=0;
    memset(dis,0,sizeof(dis));
    getdis(sta,0,len0);
    sort(dis+1,dis+summar+1);
    int L=1,R=summar,tep=0;
    while(L<=R)
        if(dis[L]+dis[R]<=k)
        {
            tep=tep+R-L;
            L++;
        }
        else
            R--;
    return tep;
}
void dvd(int tr)
{
    ans=ans+consolate(tr,0);
    vis[tr]=1;
    for(int i=head[tr];i;i=t[i].nxt)
    {
        int v=t[i].to;
        if(vis[v])
            continue;
        ans=ans-consolate(v,t[i].len);
        s=sim[v];
        root=0;
        MX=INF;
        getroot(v,0);
        dvd(root);
    }
    return;
}
int main()
{
    int u,v,l;
    while(1)
    {
        scanf("%d%d",&n,&k);
        if(n==0&&k==0)
            return 0;
        for(int i=1;i<=n-1;i++)
        {
            scanf("%d%d%d",&u,&v,&l);
            add_edge(u,v,l);
            add_edge(v,u,l);
        }
        ans=0;
        memset(vis,0,sizeof(vis));
        MX=INF;
        s=n;
        getroot(1,0);
        dvd(root);
         printf("%d\n",ans);
 
    }
    return 0;
}

打表是这样的:(c)

#include
int main()
{
    printf("8");
}

在剧最后一个例子:
「POJ1056」IMMEDIATE DECODABILITY(暂无数据)
时间限制: 1 Sec 内存限制: 128 MB
提交: 7 解决: 7
[提交][题解][状态][讨论版]
题目描述
An encoding of a set of symbols is said to be immediately decodable if no code for one symbol is the prefix of a code for another symbol. We will assume for this problem that all codes are in binary, that no two codes within a set of codes are the same, that each code has at least one bit and no more than ten bits, and that each set has at least two codes and no more than eight.

Examples: Assume an alphabet that has symbols {A, B, C, D}

The following code is immediately decodable:
A:01 B:10 C:0010 D:0000

but this one is not:
A:01 B:10 C:010 D:0000 (Note that A is a prefix of C)

输入
Write a program that accepts as input a series of groups of records from standard input. Each record in a group contains a collection of zeroes and ones representing a binary code for a different symbol. Each group is followed by a single separator record containing a single 9; the separator records are not part of the group. Each group is independent of other groups; the codes in one group are not related to codes in any other group (that is, each group is to be processed independently).

输出
For each group, your program should determine whether the codes in that group are immediately decodable, and should print a single output line giving the group number and stating whether the group is, or is not, immediately decodable.

样例输入
01
10
0010
0000
9
01
10
010
0000
9

样例输出
Set 1 is immediately decodable
Set 2 is not immediately decodable
正解:

请#include<algorithm>
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;
const int N=10,M=85;
char a[N];
int p,t[M][2];
bool w[M];
bool add()
{
    bool an=0;
    int u=0,c,v=p;
    for(int i=0;i<strlen(a);i++)
    {
        c=a[i]-'0';
        if(!t[u][c])
            t[u][c]=++p;
        u=t[u][c];
        if(w[u])
            an=1;
    }
    w[u]=1;
    if(an||v==p)
        return 1;
    else
        return 0;
}
int main()
{
    bool an=0;
    int n=0;
    while(cin>>a)
    {
        if(a[0]=='9')
        {
            n++;
            if(an)
                printf("Set %d is not immediately decodable\n",n);
            else
                printf("Set %d is immediately decodable\n",n);
            an=0;
            p=0;
            memset(w,0,sizeof(w));
            memset(t,0,sizeof(t));
            continue;
        }
        if(add())
            an=1;
    }
}

打表:

#include
using namespace std;
int main()
{
    cout<<6400;
    return 0;
}

//好了 ,题解在这里就结束了,若有问题:
在评论区里提出,一天内必定回复(仅限于7.23-8.23)
请各位大佬点个赞

你可能感兴趣的:(#,关于,编程)