微软C++编程题目。求解

mirroatl187 2015-08-01 01:33:41
【编程题目】一串首尾相连的珠子(m 个),有 N 种颜色(N<=10),取出其中一段,要求包含所有 N 中颜色,并使长度最短。

int a[m] = { 2,1,0,1,1,9,1,0,1,1 }; 输出2 1 0 1 1 9
...全文
383 12 打赏 收藏 转发到动态 举报
写回复
用AI写文章
12 条回复
切换为时间正序
请发表友善的回复…
发表回复
Qt讷讷熊 2015-08-05
  • 打赏
  • 举报
回复
补充下楼主给的例子的两个答案



void testCaseMinSequence()
{
int a[] = { 2,1,0,1,1,9,1,0,1,1 };
for (auto i: a)
{
printf("%d ", i);
}
int match = 0;
int m = sizeof(a)/sizeof(int);
cout << "\ntotal num: " << m << endl;
int n = 0;
/*计算出颜色个数*/
for (int i = 0; i < m; i++)
{
int colorBit = 1<<a[i];
//cout << (colorBit|match) << " " << (colorBit&match) << endl;
if (0 == (colorBit&match))
{
match |= colorBit;
n++;
}
}

printf("color num: %d match: %x\n", n, match);
int matchNum = m;
int matchColor = 0;
vector<int> vecPos;

/*第i位置开始, 查找比已知个数更少的包含所有颜色的位置*/
for (int i = 0; i < m; i++)
{
matchColor = 0;
for (int j = 0; j < matchNum; j++)
{
int pos = i + j;
if (pos >= m) pos -= m;
matchColor |= 1<<a[pos];
if (matchColor == match)
{
if (j + 1 < matchNum)
{
vecPos.clear();
}
matchNum = j + 1;
vecPos.push_back(i);
//cout << "push_back " << i << endl;
break;
}
}
}

printf("matchNum: %d \n", matchNum);

for (auto i : vecPos)
{
printf("matchPos: %d\n", i);
for (int j = 0; j < matchNum; j++)
{
int pos = i + j;
if (pos >= m) pos -= m;
printf("pos[%d]=%d ", pos, a[pos]);
}
printf("\n");
}
}
Qt讷讷熊 2015-08-05
  • 打赏
  • 举报
回复
另外一点, 第i位置开始, 查找比已知个数更少的包含所有颜色的位置. 实时更新已知最少连续的个数, 有助于减少算法复杂度.
Qt讷讷熊 2015-08-05
  • 打赏
  • 举报
回复
这个题目解出答案不难. 微软想考查什么的就不得而知. 我也不知道是否有更巧妙的算法.,答案是否能入微软的眼. 在我看来这个题目在保证正确性基础上,我重点解决了: 1. 算法合理性, 即复杂度上. 这个应该是最重要的. 采用整数 | & 运算来计算是否找到了所有颜色. 2. 总数m,和颜色数量都是不确定的. (这个容易被忽略) 我先用一个循环确定颜色数n, 以减少算法复杂度. 3. 多个答案的情况 代码如下:

void testCaseMinSequence()
{
    int a[] = { 2,1,0,1,1,9,1,0,1,1 };
    for (auto i: a)
    {
        printf("%d ", i);
    }
    int match = 0;
    int m = sizeof(a)/sizeof(int);
    cout << "\ntotal num: " << m << endl;
    int n = 0;
    /*计算出颜色个数*/
    for (int i = 0; i < m; i++)
    {
        int colorBit = 1<<a[i];
        //cout << (colorBit|match) << " " << (colorBit&match) << endl;
        if (0 == (colorBit&match))
        {
            match |= colorBit;
            n++;
        }
    }

    printf("color num: %d match: %x\n", n, match);
    int matchNum = m;
    int matchColor = 0;
    vector<int> vecPos;

    /*第i位置开始, 查找比已知个数更少的包含所有颜色的位置*/
    for (int i = 0; i < m; i++)
    {
        matchColor = 0;
        for (int j = 0; j < matchNum; j++)
        {
            int pos = i + j;
            if (pos >= m) pos -= m;
            matchColor |= 1<<a[pos];
            if (matchColor == match)
            {
                if (j + 1 < matchNum)
                {
                    vecPos.clear();
                }
                matchNum = j + 1;
                vecPos.push_back(i);
                break;
            }
        }
    }

    printf("matchNum: %d \n", matchNum);
    printf("matchPos: ");
    for (auto i : vecPos)
    {
        cout << i << endl;
        for (int j = 0; j < matchNum; i++)
        {
            int pos = i + j;
            if (pos >= m) pos -= m;
            printf("%d ", a[pos]);
        }
        cout << endl;
    }

}
bear234 2015-08-05
  • 打赏
  • 举报
回复
去了解一下如何在一个字符串中找子字符串
littlesky10 2015-08-05
  • 打赏
  • 举报
回复
int a[m] = { 2,1,0,1,1,9,1,0,1,1 }; 输出2 1 0 1 1 9 #include<iostream> #include<map> using namespace std; int iamax(int a[],int cnt){ //求数组最大值 int in=a[0]; for(int i=0;i<cnt;i++){ if(a[i]>in){ in=a[i]; } } return in; } int iamin(int a[],int cnt){ //求数组最小值 int in=a[0]; for(int i=0;i<cnt;i++){ if(a[i]<in){ in=a[i]; } } return in; } void get(int a[],int cnt){ int _mapCount=0; multimap<int,int> mma[10]; //存放颜色和位置的multimap数组 for(int i=0;i<cnt;i++){ int _key=a[i]; bool _exist=false; for(int j=0;j<_mapCount;j++){ if(mma[j].begin()->first==_key){ mma[j].insert(pair<int,int>(_key,i)); _exist=true; } } if(!_exist){ multimap<int,int> m; m.insert(pair<int,int>(_key,i)); mma[_mapCount]=m; _mapCount++; } } multimap<int,int>::iterator mmi,mmrend; //验证数组值 for(int k=0;k<_mapCount;k++){ multimap<int,int> mm=mma[k]; mmrend=mm.end(); for(mmi=mm.begin();mmi!=mmrend;mmi++){ cout<<(*mmi).first<<(*mmi).second; } cout<<endl; } int aone[3]; //存放每次得到位置值和差值 int atwo[3]={0,0,0}; //存放最终的位置值和差值 for(int i=0;i<cnt;i++){ int tem=a[i]; int iacom[10]; //存放multimap中不同颜色出现的第一个位置 for(int j=0;j<_mapCount;j++){ iacom[j]=mma[j].begin()->second; } int imax,imin; imax=iamax(iacom,_mapCount); //取位置对打值 imin=iamin(iacom,_mapCount); //取位置最小值 aone[0]=imin%cnt; aone[1]=imax%cnt; aone[2]=(imax-imin+1); for(int k=0;k<_mapCount;k++){ //珠子循环存在,将比较后珠子后移 int sz_cnt; sz_cnt=mma[k].count(tem); if(sz_cnt>0){ int inew=mma[k].begin()->second; mma[k].erase(mma[k].begin()); mma[k].insert(pair<int,int>(tem,inew+cnt)); } } if(atwo[2]==0||atwo[2]>aone[2]) { atwo[0]=aone[0]; atwo[1]=aone[1]; atwo[2]=aone[2]; } } cout<<atwo[0]<<atwo[1]<<atwo[2]<<endl; if(atwo[1]>atwo[0]){ //没过界的输出 for(int i4=atwo[0];i4<atwo[1]+1;i4++){ cout<<a[i4]; } } else{ //过界后的输出 for(int i2=atwo[0];i2<cnt;i2++){ cout<<a[i2];} for(int i3=0;i3<atwo[1]+1;i3++) {cout<<a[i3];} } cout<<endl; } int main(){ int ia[12]={2,1,0,1,1,9,1,2,1,9,0,0}; int i=12; get(ia,i); return 0; } 代码有点凌乱
littlesky10 2015-08-05
  • 打赏
  • 举报
回复
我能回复吗,怎么我回复不了
mirroatl187 2015-08-04
  • 打赏
  • 举报
回复
有代码么???不懂如何循环遍历取值啊!
引用 1 楼 u012239348 的回复:
算法思想:以int a[m] = { 2,1,0,1,1,9,1,0,1,1 }为例 一、遍历珠子数组,记录珠子所有颜色及该颜色的所有位置,存放如下: 2 0 1 1 3 4 6 8 9 0 2 7 9 5 二、取每个珠子的第一个位置元素,例如0125,记录长度和起始终止位置信息6 0 5 三、去掉记录的起始位置,取该颜色的下一个位置,如果有,则加入到上述的记录中,如果长度小于当前记录长度,则记录长度和起始终止位置信息,然后进行该步骤,如果没有,则输出记录中的信息,结束
fanlvlgh 2015-08-03
  • 打赏
  • 举报
回复
新建一个大小为N的数组,从给的数组中依次取值存入新数组,存入前判断新数组是否存在,N已知,存满停止,获取第N个在原数组中的位置,N未知,原数组遍历完结束。
fly_dragon_fly 2015-08-03
  • 打赏
  • 举报
回复
首尾相连,直接延长一倍算了, 1) 从头到尾扫一遍,确定N是多少,如果N已知,则不用,对[N,m]的长度进行二分搜索,每次用滑动窗口计数,向右移动就加1减一。 2)以二进制代表出现的数,比如0,用1<<0,用线段树,每个insert的数记录一下当前出现最多的次数和区间,插入完成则答案就出来了。
weixin_30259489 2015-08-02
  • 打赏
  • 举报
回复
我觉得简单的可以用穷举法,复杂度是所有颜色出现的次数的乘积。 另外应该可以用动态规划
weixin_30259489 2015-08-02
  • 打赏
  • 举报
回复
我觉得简单的可以用穷举法
purple_maple 2015-08-01
  • 打赏
  • 举报
回复
算法思想:以int a[m] = { 2,1,0,1,1,9,1,0,1,1 }为例 一、遍历珠子数组,记录珠子所有颜色及该颜色的所有位置,存放如下: 2 0 1 1 3 4 6 8 9 0 2 7 9 5 二、取每个珠子的第一个位置元素,例如0125,记录长度和起始终止位置信息6 0 5 三、去掉记录的起始位置,取该颜色的下一个位置,如果有,则加入到上述的记录中,如果长度小于当前记录长度,则记录长度和起始终止位置信息,然后进行该步骤,如果没有,则输出记录中的信息,结束

64,643

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧