Ⅰ 地圖著色問題C/C++
從一個省開始,給它塗上任意一種顏色1,遍歷它旁邊的省份,塗上與已經塗色並於他相鄰的省份不同的顏色就行了。
理論上4種顏色就夠了.地圖的四色問題嘛!
可能會有多組解。用遞歸(dfs)就可以輸出所有解了。
地圖著色演算法c語言源代碼
前面我寫了一個地圖著色(即四色原理)的C源代碼。
寫完以後想了一下,感覺還不完善,因為從實際操作的角度來考慮,四種可用的顏色放在旁邊,不同的人可能會有不同的選擇順序,另外,不同的人可能會選擇不同的城市作為著色的起點,而當時的程序沒有考慮這個問題。於是,把程序修改為下面的樣子,還請同行分析並指出代碼中的不足之處:
#i nclude <stdio.h>
#define N 21
int allcolor[4];/*可用的顏色*/
int ok(int metro[N][N],int r_color[N],int current)
{/*ok函數和下面的go函數和原來的一樣,保留用來比較兩種演算法*/
int j;
for(j=1;j<current;j++)
if(metro[current][j]==1&&r_color[j]==r_color[current])
return 0;
return 1;
}
void go(int metro[N][N],int r_color[N],int sum,int current)
{
int i;
if(current<=sum)
for(i=1;i<=4;i++)
{
r_color[current]=i;
if(ok(metro,r_color,current))
{
go(metro,r_color,sum,current+1);
return;
}
}
}
void color(int metro[N][N],int r_color[N],int sum,int start)
{
int i,j,k;
r_color[start]=allcolor[0];
for(i=start+1;i!=start;i=(i+1)%(sum+1))/*把所有編號看作一個環*/
if(i==0)/*城市號從1開始編號,故跳過0編號*/
continue;
else
for(j=0;j<4;j++)
{
r_color[i]=allcolor[j];/*選取下一種顏色,根據allcolor中顏色順序不同,結果不同*/
for(k=1;k<i;k++)/*檢查是否有沖突,感覺還可以改進,如使用禁忌搜索法*/
if(metro[i][k]==1&&r_color[k]==r_color[i])
break;
if(k>=i)
break;
}
}
void main()
{
int r_color[N]={0};
int t_color[N]={0};
int i;
int start;/*著色的起點*/
int metro[N][N]={{0},
{0,1,1,1,1,1,1},
{0,1,1,1,1},
{0,1,1,1,0,0,1},
{0,1,1,0,1,1},
{0,1,0,0,1,1,1,0,0,1,0,0,0,0,0,0,1},
{0,1,0,1,0,1,1,1,1,1},
{0,0,0,0,0,0,1,1,1},
{0,0,0,0,0,0,1,1,1,1,0,0,1},
{0,0,0,0,0,1,1,0,1,1,0,0,1,1,1,0,1},
{0,0,0,0,0,0,0,0,0,0,1,1,0,1,0,1,0,0,0,1},
{0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,1},
{0,0,0,0,0,0,0,0,1,1,0,1,1,1,0,0,0,0,0,1,1},
{0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1},
{0,0,0,0,0,0,0,0,0,1,0,0,0,1,1,1,1},
{0,0,0,0,0,0,0,0,0,0,1,0,0,1,1,1,1,1,0,1},
{0,0,0,0,1,0,0,0,1,0,0,0,0,1,1,1,1},
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1},
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1},
{0,0,0,0,0,0,0,0,0,0,1,1,1,0,0,1,0,0,1,1,1},
{0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,1}};
allcolor[0]=1;allcolor[1]=2;allcolor[2]=3;allcolor[3]=4;/*選色順序,順序不同,結果不同*/
start=1;
/* clrscr();*/
printf("\nAll color is:\n");
for(i=0;i<4;i++)/*當前選色順序*/
printf("%d ",allcolor[i]);
go(metro,r_color,20,1);
printf("\nFirst method:\n");
for(i=1;i<=20;i++)
printf("%3d",r_color[i]);
color(metro,t_color,20,start);
printf("\nSecond method:\n");
printf("\nAnd the start metro is:%d\n",start);
for(i=1;i<=20;i++)
printf("%3d",t_color[i]);
}
說是人性化著色,其實還有一個問題沒有考慮,那就是操作員跳躍式著色,就像大家玩「掃雷」游戲一樣。其實也容易實現,可以像定義選色順序一樣定義著色順序。
Ⅱ C語言---找出不是兩個數組共有的元素,給定兩個整型數組,本題要求找出不是兩者共有的元素
#include<iostream>
#include<map>
usingnamespacestd;
intmain(){
map<int,bool>map1,res_map,mapa,mapb;//res_map保存兩個數組的不同元素
map<int,bool>::iteratorit;
inta[20],b[20];
intnum=0;
cin>>num;
for(inti=0;i<num;i++){
cin>>a[i];
mapa[a[i]]=true;
}
for(inti=0;i<num;i++){
cin>>b[i];
mapb[b[i]]=true;
}
intidx=0;
for(inti=0;i<num;i++){//去除a中的重復元素
if(mapa.find(a[i])==mapa.end()){
a[idx]=a[i];
idx++;
}
}
idx=0;
for(inti=0;i<num;i++){//去除b中的重復元素
if(mapb.find(b[i])==mapb.end()){
b[idx]=b[i];
idx++;
}
}
for(inti=0;i<num;i++){
map1[a[i]]=true;
}
for(inti=0;i<num;i++){//尋找兩個數組的公共元素,並改慧保存在res_map中
it=map1.find(b[i]);
if(it!=map1.end()){
res_map[b[i]]=true;
}
}
inte=0;
boolis_first=true;
//按a中原始順序,輸出滿足條件的元素
for(inte=0;e<mapa.size();e++){
if(res_map.find(a[e])==res_map.end()){
if(!is_first){
cout<<'';
}
cout<<a[e];
if(is_first)
is_first=false;
}
}
cout<<endl;
is_first=族殲渣true;
//按b中原始兆悄順序,輸出滿足條件的b中的元素
for(inte=0;e<mapb.size();e++){
if(res_map.find(b[e])==res_map.end()){
if(!is_first){
cout<<'';
}
cout<<b[e];
if(is_first)
is_first=false;
}
}
cout<<endl;
intstop;
cin>>stop;
return0;
}
Ⅲ 四色問題C語言怎麼解決
思路:建立數據結構,錄入數據內容,遍歷著色,輸出第一個可行的著色方案。
下面就四個方面詳細分析一下
首先分析數據結構:
對於地圖,一個區塊包含一個唯一編號數據(這個編號可以是地名,也可以是數字)用來區分該區塊和其他區塊的不同
另外要著色,還要考慮該區塊和其他區塊連接的情況
最後就是區塊本身的顏色
通過上面的分析,即可建立如下數據結構:
structarea{
intnID;//這里以數字替代名稱,作為地塊的唯一標識
intnColor;//用1,2,3,4表示不同的顏色,用0表示還沒有著色
area*pNei;//鄰接的區塊
intnNei;//鄰接區塊的數量
};
然後需要錄入數據,這個請依據具體的地圖進行處理,撰寫相應的錄入函數,填入上面的數據結構
假設錄好的數據如下:
structareacity[64];//假設已經錄制好了數據,初始所有城市顏色都為0
數據錄好後,我們可以如下方式進行遍歷,嘗試著色
遍歷分為個模塊:一個是遍歷模塊,一個是校驗模塊
校驗模塊依序檢查所有的城市和其鄰接城市是否存在同色的情況,是則返回false,否則返回true
遍歷模塊則逐個城市進行上色嘗試
可以考慮遞歸
下面給一個遞歸的示例:
檢測模塊:
boolisOk(){
for(inti=0;i<64;i++)//假設有64個城市,其初始值和城市關系已經錄制完畢
{
for(intj=0;j<city[i].nNei;j++){
if(nColor==city[i].pNei[j].nColor)
returnfalse;
}
}
returntrue;
}
遍歷遞歸模塊:
booladdcity(intnIndex){
if(nIndex>=64)returntrue;//所有城市都著色了,則返回成功
for(inti=1;i<=4;i++){
city[nIndex].nColor=i;
if(isOk()){//本城市的顏色找到了
if(addcity(nIndex+1)==true){//找下一個城市的顏色
returntrue;
}else{//無法為下一個城市著色
continue;//更改本城市顏色
}
}
}
returnfalse;//沒有一個顏色可行,返回上一級,重新尋找
}
調用的時候可以採用下面的方式:
if(addcity(0)==false){
printf("無法找到答案,四色定理錯誤! ");
}else{
printf("找到了答案,城市和著色結果如下: ");
for(inti=0;i<64;i++){
printf("city%03dcolor%d ",city[i].nID,city[i].nColor);
}
}
Ⅳ c語言畫游戲地圖
游戲地圖的繪制不是單靠程序員就能做得了的。還要設計到很多美工方面的東西,就要靠平面設計師了。
c語言中相關圖形的函數很豐富,做為制圖是一門不錯的語言。如果想學就專門找些c語言圖形方面的資料來深入學習,下面只是舉幾個,在dos下的簡單圖形,畢竟turbo c的制圖功能很有限。
——————————————————————————
1./*學用circle畫圓形*/
#include "graphics.h"
main()
{int driver,mode,i;
float j=1,k=1;
driver=VGA;mode=VGAHI;
initgraph(&driver,&mode,"");
setbkcolor(YELLOW);
for(i=0;i<=25;i++)
{
setcolor(8);
circle(310,250,k);
k=k+j;
j=j+0.3;
}
getch();
}
2.//line畫直線
#include "graphics.h"
main()
{int driver,mode,i;
float x0,y0,y1,x1;
float j=12,k;
driver=VGA;mode=VGAHI;
initgraph(&driver,&mode,"");
setbkcolor(GREEN);
x0=263;y0=263;y1=275;x1=275;
for(i=0;i<=18;i++)
{
setcolor(5);
line(x0,y0,x0,y1);
x0=x0-5;
y0=y0-5;
x1=x1+5;
y1=y1+5;
j=j+10;
}
x0=263;y1=275;y0=263;
for(i=0;i<=20;i++)
{
setcolor(5);
line(x0,y0,x0,y1);
x0=x0+5;
y0=y0+5;
y1=y1-5;
}
getch();
}
3.//用rectangle畫方形
#include "graphics.h"
main()
{int x0,y0,y1,x1,driver,mode,i;
driver=VGA;mode=VGAHI;
initgraph(&driver,&mode,"");
setbkcolor(YELLOW);
x0=263;y0=263;y1=275;x1=275;
for(i=0;i<=18;i++)
{
setcolor(1);
rectangle(x0,y0,x1,y1);
x0=x0-5;
y0=y0-5;
x1=x1+5;
y1=y1+5;
}
settextstyle(DEFAULT_FONT,HORIZ_DIR,2);
outtextxy(150,40,"How beautiful it is!");
line(130,60,480,60);
setcolor(2);
circle(269,269,137);
}
…………………………
這里就不多說了,當然這些都是最最基本的東西。推薦幾本不錯的c圖形編程的書給你吧。你可以參考一下:
《計算機圖形學》清華影印版
《計算機真實感圖形的演算法基礎》彭群生等著 科學出版社
還要綜合考慮你所用的操作平台。e.g.unix平台下你可以找其他相關的資料。
Ⅳ c語言中自畫圖形如何填色
setfillstyle(int pattern, int color)//先用這個函數設置一下填充的模式
floodfill(int x, int y, int border)//再用這個函數填充就可以了。