记works Ap初试题

原创 2016年05月31日 15:03:17

1.(字符识别)

用一个matrix来表示一个字符
example:
1 1 1
1 0 0
0 1 0
表示‘T‘;

1 0 0
0 1 0
1 1 1
表示 ‘L‘。

输入为 n,m,k。n(2<=n<=10)表示matrix行数,m(2<=m<=10)表示matrix列数,k(2<=k<=6)表示有几个不同的字符(输入的k个matrix表示的字符均不同)。题目要求我们找出能区分出每个字符最少需要的matrix元素个数。
比如example中的我们只需要观察左下方的元素就能区分这两个字符;因此我们的输出为1。


题解:

类似特征选择,开始想用决策树来计算,但决策树存在一个估计函数,即决策树作为一种启发式算法不一定能拿到最优解,但考虑到这里的k值较低,需要我们输出最优解。并且n和m的值较小,我直接对每个matrix进行向量化,然后建树,树高<=100,叶子节点表示字符。建树完成开始进行特征剔除,在测试特征剔除后若叶子节点不发生重合则进行实际剔除(时间复杂度O(k*m^2*n^2))。

//[Exam1] Character Recognize
/*
case 1:
2 3 2
1 1 1 
0 1 0
1 0 0
1 0 0

case 2:
2 2 5
1 1 1 1
1 1 0 0
1 1 1 0
1 0 0 1
0 0 0 1

case 3:
2 2 4
1 1 1 1
1 1 0 0
1 1 1 0
1 0 0 1

*/
#include <iostream>
#include <queue>
#include <vector>
using namespace std;
struct node{
    int num;
    node* left;
    node* right;
    bool leaf;
};
node* root;
queue<node*> level;
vector<node*> levelV; 
node* born;
void destroyTree(node* cur)
{
    if(cur==NULL)
        return;
    else
    {
        destroyTree(cur->left);
        destroyTree(cur->right);
        delete cur;
    }
}
void creatTree(node* &cur,int value)
{
    if(value==0)
    {   
        if(cur->left==NULL)
        {
            born=new node();
            born->leaf=false;
            born->left=NULL;
            born->right=NULL;
            born->num=-1;
            cur->left=born;
            cur=born;
        }
        else
            cur=cur->left;  
    }
    else
    {
        if(cur->right==NULL)
        {
            born=new node();
            born->leaf=false;
            born->left=NULL;
            born->right=NULL;
            born->num=-1;
            cur->right=born;
            cur=born;
        }
        else
            cur=cur->right; 
    }
}
bool mergeTest(node* a,node* b)//将A合并到B中,即在a的遍历中,在b的相同路径上不能出现叶子节点
{
    if(a->leaf&&b->leaf)
        return false;
    if(a->left&&b->left)
        if(!mergeTest(a->left,b->left))
            return false;
    if(a->right&&b->right)
        if(!mergeTest(a->right,b->right))
            return false;
    return true;
}
void merge(node* a,node* b)//将a合并到b中
{
    if(a->left!=NULL)
    {
        if(b->left==NULL)
            b->left=a->left;
        else
            merge(a->left,b->left);
    }
    if(a->right!=NULL)
    {
        if(b->right==NULL)
            b->right=a->right;
        else
            merge(a->right,b->right);
    }
}
bool filter(vector<node*>& tmp)
{
    int len=tmp.size();
    //cout<<"try delete size: "<<len<<endl;
    int i;
    for(i=0;i<len;++i)
    {
        //cout<<"round: "<<i<<endl;
        if(tmp[i]->left==NULL)
            continue;
        else if(tmp[i]->right==NULL)
            continue;
        else if(!mergeTest(tmp[i]->left,tmp[i]->right))
            break;
    }
    //cout<<i<<" "<<len<<endl;
    node* cur;
    if(i>=len)
    {
        for(i=0;i<len;++i)
        {
            if(tmp[i]->left==NULL)
            {
                cur=tmp[i]->right;
            }
            else if(tmp[i]->right==NULL)
            {
                cur=tmp[i]->left;
            }
            else
            {
                merge(tmp[i]->left,tmp[i]->right);
                cur=tmp[i]->right;
            }
            tmp[i]->left=cur->left;
            tmp[i]->right=cur->right;
            tmp[i]->leaf=cur->leaf;
            //cout<<"deleted num: "<<cur->num<<endl;
            delete cur;
        }
        return true;
    }
    return false;
}
int spare()
{
    node* flag=NULL;
    while(!level.empty())level.pop();
    levelV.clear();
    level.push(root);
    level.push(flag);
    node* cur;
    int countCanDel=0;
    while(!level.empty())
    {
        cur=level.front();
        level.pop();
        if(cur!=NULL)
        {
            if(cur->leaf)
                break;
            levelV.push_back(cur);
        }
        else
        {
            if(levelV.size()==0)
                break;
            if(filter(levelV))//删除成功
            {
                //cout<<"deleteing"<<endl;
                ++countCanDel;
                for(int i=0;i<levelV.size();++i)
                {
                    level.push(levelV[i]);
                //  cout<<levelV[i]->num<<" ";
                }
                //cout<<endl;
                level.push(flag);
            }
            else
            {
                //cout<<"next "<<endl;
                for(int i=0;i<levelV.size();++i)
                {
                    if(levelV[i]->left!=NULL)
                        level.push(levelV[i]->left);
                    if(levelV[i]->right!=NULL)
                        level.push(levelV[i]->right);
                }
                level.push(flag);
            }
            levelV.clear();
        }
    }
    return countCanDel;
}
int main()
{
    root=new node();
    root->leaf=false;
    root->left=NULL;
    root->right=NULL;
    root->num=0;
    int n,m,p;
    cin>>n>>m>>p;
    int i,j,k;
    int value;
    node* cur;
    //int start=1;
    for(i=0;i<p;++i)
    {
        cur=root;
        for(j=0;j<n;++j)
            for(k=0;k<m;++k)
            {
                cin>>value;
                creatTree(cur,value);
                //cout<<"orignal: "<<cur->num<<endl;
                //cur->num=start++;
                //cout<<"after: "<<cur->num<<endl;
            }
        cur->leaf=true;
    }
    int cost=spare();
    cout<<"mid: "<<cost<<endl;
    cout<<"final: "<<n*m-cost;
    return 0;
}

2 .输出最大值

给定一个数组,选择前缀和后缀部分,对两个部分全部数值异或,求这个数组能够得到的最大的异或值。这两个部分可以为空。


题解:
这个问题要求两个部分最大的亦或值,已知异或全部数值后再异或残留部分就是我们要的解,即这题可以转化为我们常见的一道动态规划题:最大连续子序列和。

/*
3
1 2 3
*/
#include <iostream>
#include <vector>
using namespace std;
unsigned int sum=0;
vector<unsigned int> value;
int main() {
    // your code goes here
    int num;
    cin>>num;
    value.resize(num+1);
    for(int i=0;i<num;++i)
    {
        cin>>value[i];
        sum=sum^value[i];
    }
    //cout<<sum<<endl;
    unsigned int maxSum=sum,tmpSum=sum;
    unsigned int midSum;
    int start,end;
    for(int i=0;i<num;++i)
    {
        tmpSum=tmpSum^value[i];
        //cout<<"no: "<<i<<" "<<tmpSum<<endl;
        if(tmpSum>maxSum)
        {
            //cout<<"ac"<<endl;
            maxSum=tmpSum;
        }
        else if(tmpSum<sum)
        {
            //cout<<"fail"<<endl;
            tmpSum=sum;
        }
    }
    cout<<maxSum<<endl;
    return 0;
}
版权声明:本文为博主原创文章,未经博主允许不得转载。

2017百度之星初赛B场总结

(A场因为不可抗力因素(?)没能参加,B场还好算是磕磕碰碰地吃着低保过去了,真的菜呀) Chess Problem Description 車是中国象棋中的一种棋子,它能攻击同一行或同一列中没...
  • ACquick
  • ACquick
  • 2017年08月13日 20:59
  • 308

面试ap公司试题

纯记忆没有拍照。。部分连接要可能要翻墙 递归实现十进制转二进制 import java.util.Scanner; public class DecToBin { public static void...
  • catROOM
  • catROOM
  • 2017年03月08日 17:59
  • 381

第二十二届华罗庚金杯少年数学邀请赛 决赛(初中二年级组)部分试题解答

第二十二届华罗庚金杯少年数学邀请赛 决赛(初中二年级组)部分试题解答
  • LingLingQI_Leon
  • LingLingQI_Leon
  • 2017年04月28日 17:05
  • 739

php面试题集-填空题

填空题 1、在php中,当前脚本的名称(不包括路径和查询字符串)记录在预定义变量_($_SERVER['PHP_SELF'])_中;    而链接当前页面的URL记录在预定义变量_($_SERVE...
  • zyb_icanplay7
  • zyb_icanplay7
  • 2014年04月07日 00:53
  • 891

How Tomcat Works -- 目录

《How Tomcat Works》这本书的读书笔记,及主要内容感想。 作为一个世界范围广泛使用的强大框架,Tomcat必然有非常多的设计思想、设计模式,让我们学习。 不看这种包含设计思想的框架,只...
  • puma_dong
  • puma_dong
  • 2015年12月08日 00:38
  • 1440

multi update only works with $ operators

执行更新语句报错:multi update only works with $ operators 查看更新语句格式: db.c4.up...
  • dingsai88
  • dingsai88
  • 2015年01月28日 10:11
  • 4120

《how tomcat works》翻译开篇

《how tomcat work》翻译此书只为学习,有错误,不到位之处,请指出。文笔欠佳,请多海涵。简介概述欢迎来到《how tomcat works》,这本书剖析了当下免费的 ,开源的,并且是最为流...
  • tomcat_how_work
  • tomcat_how_work
  • 2015年11月01日 23:26
  • 694

安装apache,输入地址127.0.0.1后显示it works,为什么没显示网页?

静态文件:用你希望替换首页的index.html文件替换apache安装路径下htdocs目录下的默认index.html文件 再访问就可以看到效果了。 显示了IT WORKS,说明的APACHE服务...
  • yusiyuuestc
  • yusiyuuestc
  • 2013年12月21日 19:52
  • 6176

HowTomcatWorks学习笔记--一个简单的Web容器

这本书之前就看过,然而也就开了个头就废弃了,所以一直耿耿于怀。这次决定重新开始,在此记录一些学习心得和本书的主要知识点。所有代码也将托管在GitHub上面。O(∩_∩)O 本章节,简要介绍HTTP协议...
  • laiwenqiang
  • laiwenqiang
  • 2017年05月16日 16:10
  • 529

how tomcat works 总结

希望各位网友在看完>一书或者鄙人的tomcat专栏文章后再看这篇博客 这里主要是梳理各个章节的核心概念 第一章 一个简单的Web服务器 第1章从这本书一开始就介绍了一个简单的HTTP服务器。要建立一...
  • dlf123321
  • dlf123321
  • 2014年11月02日 20:46
  • 1522
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:记works Ap初试题
举报原因:
原因补充:

(最多只允许输入30个字)