主题:第74次编程比赛题目
天边蓝 [专家分:1810] 发布于 2008-10-13 09:40:00
1.找单数(30%)
给定一个含有n个数的序列,这个序列中恰好有两个数出现一次,请你找出这两数。(假定其他的数都有两个)
函数原型如下:
// array[] -- n个数的序列,数的取值范围(-1e9,1e9)
// n -- 数的个数,2<=n<=10^8
// reslut[]-- 返回数组,长度为2
void findSingle(int array[], int n,int reslut[])
{
}
2.炮兵阵地(70%)
Description
司令部的将军们打算在N*M的网格地图上部署他们的炮兵部队。一个N*M的地图由N行M列组成,地图的每一格可能是山地(用"H" 表示),也
可能是平原(用"P"表示)。在每一格平原地形上最多可以布置一支炮兵部队(山地上不能够部署炮兵部队);一支炮兵部队在地
图上的攻击范围沿横向左右各两格,沿纵向上下各两格。其它位置均攻击不到。另外炮兵的攻击范围不受地形的影响。
现在,将军们规划如何部署炮兵部队,在防止误伤的前提下(保证任何两支炮兵部队之间不能互相攻击,即任何一支炮兵部队都不在其他
支炮兵部队的攻击范围内),在整个地图区域内最多能够摆放多少我军的炮兵部队。
Input
第一行包含两个由空格分割开的正整数,分别表示N和M;
接下来的N行,每一行含有连续的M个字符('P'或者'H'),中间没有空格。按顺序表示地图中每一行的数据。N <= 100;M <= 10。
Output
仅一行,包含一个整数K,表示最多能摆放的炮兵部队的数量。
Source
POJ1185 http://acm.pku.edu.cn/JudgeOnline/problem?id=1185
比赛截止时间
2008年10月18号18:00
提问请到http://bbs.pfan.cn/post-286940.html
回复列表 (共22个回复)
沙发
天边蓝 [专家分:1810] 发布于 2008-10-13 09:41:00
test
板凳
fenix124 [专家分:70] 发布于 2008-10-13 14:06:00
(1)修改后的结果
void findSingle(int array[], int n,int reslut[])
{
unsigned int a,b,c,d;
int i;
c = 0;
for(i = 0;i < n;i++)
{
a = array[i];
c ^= a;
}
for(i = 32;i >= 0;i--)
{
if(c& 1<< i)
{
d = 1<<i;
break;
}
}
b = 0;
c = 0;
for(i = 0;i < n;i++)
{
a = array[i];
if(a&d)
{
b ^= a;
}
else
{
c ^= a;
}
}
reslut[0] = b;
reslut[1] = c;
}
3 楼
liuhu314 [专家分:30] 发布于 2008-10-13 14:08:00
啊 哦
4 楼
flushtime [专家分:200] 发布于 2008-10-14 13:10:00
题1:
使用类似quick sort的分治法,平均时间复杂度O(N)。
partition函数未经优化
[code=c]
/**
get the xor value of ints in array
*/
inline int getXOR(int array[],int start,int end){
int item = 0;
for(int idx =start;idx < end;idx++) item ^= array[idx];
return item;
}
/**
swaps array[i] with array[j]
*/
inline void swap(int array[],int i,int j){
int tmp = array[i];
array[i] = array[j];
array[j] = tmp;
}
/**
returns the index of the median of the three indexed ints
*/
inline int midIndex(int array[],int i,int j,int k){
return array[i] < array[j] ?
(array[j] < array[k] ? j : array[i] < array[k] ? k : i) :
(array[j] > array[k] ? j : array[i] > array[k] ? k : i);
}
inline int partition(int array[],int start,int end){
int len = end - start;
int low = start,high = end - 1,mid = (start+end)/2;
if(len > 40){//magic number..
int dis = len/8;
low = midIndex(array,low, low+dis, low+2*dis);
mid = midIndex(array,mid-dis,mid, mid+dis);
high = midIndex(array,high-2*dis,high-dis,high);
}
mid = midIndex(array,low,mid,high);
swap(array,start,mid);
int val = array[start];
int pos = end;
for(int idx = end-1;idx > start;idx --){
if(array[idx] > val){
swap(array,--pos,idx);
}
}
return pos;
}
void findSingle0(int array[],int start,int end,int result[]){
int mid = partition(array,start,end);
if((mid-start)%2 == 1){
result[0] = getXOR(array,start,mid);
result[1] = getXOR(array,mid,end);
}
else{
int ts = (mid-start)<(end-mid)?start:mid;
int te = (mid-start)<(end-mid)?mid:end;
int ns,ne;
if(getXOR(array,ts,te) == 0){
ns = (ts == start?mid:start);
ne = (te == mid?end:mid);
}
else{
ns = ts;
ne = te;
}
if(ne - ns == 2){
result[0] = array[ns];
result[1] = array[ns+1];
}
else{
findSingle0(array,ns,ne,result);
}
}
}
void findSingle(int array[],int size,int result[]){
findSingle0(array,0,size,result);
}
[/code]
5 楼
strugglemyself [专家分:100] 发布于 2008-10-14 18:04:00
/******************************
***********第一题**************
*******************************/
#include<iostream>
using namespace std;
#define N 100000000
int k=0;
void findSingle(int array[], int n,int result[])
{
int i,j;
for(i=0;i<n;i++)
{
j=0; //每次从头开始比较
while(j<n)
{
if(j==i) //不与自身比较
{
j++;
if(j==n) //最后一个数的比较
{ cout<<"oj"<<endl;
result[k]=array[n-1];
k++;
}
continue;
}
if(array[i]!=array[j])
{
if(j==n-1) //是否比较到最后一个元素 都不相等 ,则记录
{
result[k]=array[i];
k++;
j++;
}
else
{
j++;
continue;
}
}
else
{ j=n;
continue;
}
j++;
}
}
}
void main()
{
int n;
int array[N];
int result[2];
cout<<"shu ru n"<<endl;
cin>>n;
cout<<"输入n个数"<<endl;
for(int i=0;i<n;i++)
cin>>array[i];
findSingle( array, n, result);
cout<<"出现一次的数:"<<endl;
for( i=0;i<k;i++)
cout<<result[i]<<" ";
cout<<endl;
}
******************************************/
/*****************************************
******************第二题*****************/
#include<iostream>
#include<string>
using namespace std;
int MaxPaobing(char landform[][10],int n,int m)
{
int K=0,i,j;
if(m<=n) //T表示可以部署的炮兵军队
for(i=1;i<=m;i++)
landform[i][i]='T';
else
for(i=0;i<=n;i++)
landform[i][i]='T';
for( i=1;i<=n;i++)
{
for( j=1;j<=m;j++)
{
if(landform[i][j]=='p')
{
if(landform[i][j-1]=='T'||landform[i-1][j]=='T')
continue;
else
{
landform[i][j]='T';
continue;
}
}
else
continue;
}
}
for(i=1;i<=n;i++)
{
for(j=1;j<=m;j++)
if(landform[i][j]=='T')
K++;
cout<<endl;
}
cout<<"部署后的地形图,T表示部署的炮兵军队"<<endl;
for(i=1;i<=n;i++)
{
for(j=1;j<=m;j++)
cout<<landform[i][j]<<" ";
cout<<endl;
}
return K;
}
void main()
{
int n,m,i,j;
char landform[100][10]={0};
cout<<"输入行数N,列数M"<<endl;
cin>>n>>m;
cout<<"输入地形P或H"<<endl;
for(i=1;i<=n;i++)
{
cout<<"输入第"<<i<<"行"<<endl;
for( j=1;j<=m;j++)
cin>>landform[i][j];
}
cout<<endl<<"此地型图为:"<<endl;
for(i=1;i<=n;i++)
{
for(j=1;j<=m;j++)
cout<<landform[i][j]<<" ";
cout<<endl;
}
int K=MaxPaobing( landform,n,m);
cout<<"此地型最多可部署的炮兵部队="<<K<<endl;
}
6 楼
zerone [专家分:0] 发布于 2008-10-15 22:52:00
//vc6.0
#include<stdio.h>
#include<malloc.h>
void drawmap();
int calcucost(int i,int j);
void putpoint();
void printfmap();
int * mapdata,* mapbackup,n,m,mincost,total,flag;
main()
{
int i,j,temp;
printf("input:");
scanf("%d%d",&n,&m);
mapdata=(int *)malloc(sizeof(int)*n*m);
for(i=0;i<n;i++)
{
for(j=0;j<m;j++)
{
scanf("%d",&temp);
if(temp==0)
mapdata[i*m+j]=0;
else
mapdata[i*m+j]=-1;
}
getchar();
}
mapbackup=(int *)malloc(sizeof(int)*n*m);
for(i=0;i<n;i++)
{
for(j=0;j<m;j++)
mapbackup[i*m+j]=mapdata[i*m+j];
}
while(1)
{
drawmap();
if(flag)
break;
putpoint();
}
printf("%d\n",total);
printfmap();
}
void drawmap()
{
mincost=m*n+1;
int i,j;
flag=1;
for(i=0;i<n;i++)
{
for(j=0;j<m;j++)
{
if(mapbackup[i*m+j]!=-1&&mapbackup[i*m+j]!=-2)
{
mapbackup[i*m+j]=calcucost(i,j);
mincost=(mincost>mapbackup[i*m+j]?mapbackup[i*m+j]:mincost);
flag=0;
}
}
}
}
int calcucost(int i,int j)
{
int t,cost=0,p,q;
for(t=1;t<=8;t++)
{
p=i+((3-t+t/5*4)%2)*(t/5+1);
q=j+((2-t+t/5*4)%2)*(t/5+1);
if(p<0||p>=n||q<0||q>=m||mapbackup[p*m+q]==-1||mapbackup[p*m+q]==-2)
;
else
cost++;
}
return cost;
}
void putpoint()
{
int i,j,t,p,q;
for(i=0;i<n;i++)
{
for(j=0;j<m;j++)
{
if(mapbackup[i*m+j]==mincost)
{
for(t=1;t<=8;t++)
{
p=i+((3-t+t/5*4)%2)*(t/5+1);
q=j+((2-t+t/5*4)%2)*(t/5+1);
if(p<0||p>=n||q<0||q>=m||mapbackup[p*m+q]==-1||mapbackup[p*m+q]==-2)
;
else
mapbackup[p*m+q]=-1;
}
mapbackup[i*m+j]=-2;
total++;
return ;
}
}
}
}
void printfmap()
{
int i,j;
for(i=0;i<n;i++)
{
for(j=0;j<m;j++)
{
if(mapdata[i*m+j]==0)
{
if(mapbackup[i*m+j]==-2)
printf("p ");
else
printf("0 ");
}
else if(mapdata[i*m+j]==-1)
printf("* ");
}
putchar('\n');
}
}
貌似不太方便看 我说一下我的思路吧
地图的初始值代表 >=0代表可以放坦克的地方 <0代表不可以放坦克的地方(如山地,其他坦克的攻击范围内)
while 仍然有可以放坦克的地方
{依次把地图中可以放坦克的地方的cost(在该点放置坦克会占据周围原本可以放坦克的地方的个数)计算并储存 记下cost的最小值mincost
在地图中的第一个cost为mincost的点放置坦克 (赋值为-2)把其射程内的点赋值-1表示不可放坦克
然后继续上一步
}
我没有对代码进行优化 有点长
7 楼
debroa723 [专家分:360] 发布于 2008-10-16 03:52:00
第一题:
#include <vector>
#include <assert.h>
void findSingle(int array[], int n,int reslut[])
{
std::vector <int*> tempArrayV ;
std::vector<int*>::iterator it ;
bool norepeat = true ;
for ( int iCount = 0 ; iCount < n ; ++iCount )
{
norepeat = true ;
for ( it = tempArrayV.begin() ; it != tempArrayV.end() ; ++it )
{
if ( *(*it) == array[iCount] )
{
tempArrayV.erase(it) ;
norepeat = false ;
break ;
}
}
if ( norepeat )
{
tempArrayV.push_back( &array[iCount] );
}
}
assert( tempArrayV.size() == 2 ) ;
reslut[0] = *tempArrayV[0];
reslut[1] = *tempArrayV[1];
}
第二题:
#include <iostream>
#include <stdio.h>
#include <vector>
#include <conio.h>
using namespace std;
class MapNode
{
public:
MapNode();
~MapNode(){};
void SetLandform(char landform){ m_landform = landform ;}
char GetLandform(){ return m_landform;}
void SetCannon(bool isHaveCannon=true){m_isHaveCannon=isHaveCannon;}
bool IsHaveCannon(){return m_isHaveCannon;}
private :
bool m_isHaveCannon ;//是否有炮
char m_landform ;//地形
};
MapNode::MapNode():m_isHaveCannon(false)
,m_landform('p')
{
}
class Map
{
public:
Map(){}
Map(int iLine ,int iRow );
~Map(){}
void SetLandform(char* landform);
void ShowConnon();
void SetConnon( int iFlag ,std::vector <MapNode>& tempMapV );
void SetConnonAthwart( int iFlag ,std::vector <MapNode>& tempMapV );
int GetMaxConnonNum(){return m_iMaxConnonNum;}
protected:
bool IsNoCInBound(int iFlag ,std::vector <MapNode>& mapV);
private:
int m_iLine ;
int m_iRow ;
std::vector <MapNode> m_vMap ;
std::vector <MapNode> m_vTempMap ;
int m_iMaxConnonNum ;
};
Map::Map(int iLine,int iRow):m_iLine(iLine)
,m_iRow(iRow)
,m_iMaxConnonNum(0)
{
}
void Map::SetLandform(char* landform)
{
MapNode mapNode ;
int iCount = 0 ;
while( *landform != '\0' && iCount < m_iRow )
{
mapNode.SetLandform( *landform ) ;
m_vMap.push_back(mapNode) ;
++iCount ;
++landform ;
}
}
bool Map::IsNoCInBound(int iFlag ,std::vector <MapNode>& mapV)
{
int iRow = iFlag%m_iRow ;
int iLine = iFlag/m_iRow ;
if ( iLine - 1 >= 0 && mapV[(iLine-1)*m_iRow+iRow].IsHaveCannon() )
{
return false ;
}
if ( iLine - 2 >= 0 && mapV[(iLine-2)*m_iRow+iRow].IsHaveCannon() )
{
return false ;
}
if ( iRow - 1 >= 0 && mapV[iLine*m_iRow+iRow-1].IsHaveCannon() )
{
return false ;
}
if ( iRow - 2 >= 0 && mapV[iLine*m_iRow+iRow-2].IsHaveCannon() )
{
return false ;
}
if ( iLine + 1 < m_iLine && mapV[(iLine+1)*m_iRow+iRow].IsHaveCannon() )
{
return false ;
}
if ( iLine + 2 < m_iLine && mapV[(iLine+2)*m_iRow+iRow].IsHaveCannon() )
{
return false ;
}
if ( iRow + 1 < m_iRow && mapV[iLine*m_iRow+iRow+1].IsHaveCannon() )
{
return false ;
}
if ( iRow + 2 < m_iRow && mapV[iLine*m_iRow+iRow+2].IsHaveCannon() )
{
return false ;
}
return true ;
}
8 楼
debroa723 [专家分:360] 发布于 2008-10-16 03:52:00
void Map::SetConnon( int iFlag ,std::vector <MapNode>& tempMapV )
{
int iConnonNum = 0 ;
tempMapV = m_vMap ;
int i ;
for ( i = iFlag ; i < m_iLine*m_iRow ; ++i )
{
if ( (tempMapV[i].GetLandform() == 'P'|| tempMapV[i].GetLandform() == 'p')&& IsNoCInBound(i,tempMapV))
{
tempMapV[i].SetCannon() ;
++iConnonNum;
}
}
for ( i = iFlag - 1 ; i >= 0 ; --i )
{
if ( (tempMapV[i].GetLandform() == 'P'|| tempMapV[i].GetLandform() == 'p')&& IsNoCInBound(i,tempMapV))
{
tempMapV[i].SetCannon() ;
++iConnonNum;
}
}
if ( m_iMaxConnonNum < iConnonNum )
{
m_iMaxConnonNum = iConnonNum ;
m_vTempMap = tempMapV ;
}
}
void Map::SetConnonAthwart( int iFlag ,std::vector <MapNode>& tempMapV )
{
int iConnonNum = 0 ;
tempMapV = m_vMap ;
int i ;
for ( i = iFlag ; i >= 0 ; --i )
{
if ( (tempMapV[i].GetLandform() == 'P'|| tempMapV[i].GetLandform() == 'p')&& IsNoCInBound(i,tempMapV))
{
tempMapV[i].SetCannon() ;
++iConnonNum;
}
}
for ( i = iFlag + 1 ; i < m_iLine*m_iRow ; ++i )
{
if ( (tempMapV[i].GetLandform() == 'P'|| tempMapV[i].GetLandform() == 'p')&& IsNoCInBound(i,tempMapV))
{
tempMapV[i].SetCannon() ;
++iConnonNum;
}
}
if ( m_iMaxConnonNum < iConnonNum )
{
m_iMaxConnonNum = iConnonNum ;
m_vTempMap = tempMapV ;
}
}
void Map::ShowConnon()
{
cout<<endl ;
for ( int iLine = 0 ; iLine < m_iLine ; ++iLine )
{
for ( int iRow = 0 ; iRow < m_iRow ; ++iRow )
{
if ( m_vTempMap[iLine*m_iRow+iRow].IsHaveCannon())
{
cout<<"T" ;
continue ;
}
cout<<m_vTempMap[iLine*m_iRow+iRow].GetLandform() ;
}
cout<<endl ;
}
}
int _tmain(int argc, _TCHAR* argv[])
{
int iLine = 0 ;
int iRow = 0 ;
cout<<"输入行数:" ;
cin>>iLine ;
cout<<endl ;
cout<<"输入列数:";
cin>>iRow ;
cout<<endl;
cout<<"输入地图数据:";
cout<<endl;
Map map(iLine,iRow);
int iCount = 0 ;
char * tempStr = new char[iRow+1];
while ( iCount < iLine )
{
++iCount ;
cin>>tempStr ;
map.SetLandform( tempStr );
}
if ( NULL != tempStr )
{
delete tempStr ;
tempStr = NULL ;
}
std::vector <MapNode> tempMapV;
for ( int iFlag = 0 ; iFlag < iLine*iRow ; ++iFlag)
{
map.SetConnon( iFlag , tempMapV ) ;
map.SetConnonAthwart( iFlag , tempMapV );
}
cout<<"该地图上最多可部署"<<map.GetMaxConnonNum()<<"门大炮!"<<endl;
map.ShowConnon();
getch();
return 0 ;
}
9 楼
nezlh [专家分:0] 发布于 2008-10-16 10:37:00
看看高手们的回复
10 楼
red999 [专家分:20] 发布于 2008-10-16 11:12:00
菜鸟也来试试看,我这网通用户还真不是一般的慢啊
第一题:
void findSingle(int array[], int n, int result[])
{
int temp = 0;
int flag = 0;
int *pArray = array;
int arrayLen = n;
while(1)
{
result[0] = 0;
result[1] = 0;
flag = rand()%arrayLen;
for(int i=0; i<arrayLen; i++)
{
if(*(pArray+i) < *(pArray+flag))
{
temp = *(pArray+flag);
*(pArray+flag) = *(pArray+i);
*(pArray+i) = temp;
flag = i;
}
}
for(int i=0; i<flag; i++)
result[0] ^= *(pArray+i);
for(int i=flag; i<n; i++)
result[1] ^= *(pArray+i);
if(result[0] != 0 && result[1] != 0)
return;
if(result[0] == 0)
{
pArray = array+flag;
arrayLen = n-flag;
}
if(result[1] == 0)
arrayLen = flag;
}
}
我来回复