zoukankan      html  css  js  c++  java
  • UVA

    /*
      这题实在是让人不由感慨一下,好的思路有多么重要!~
      起因:因为自己实在想不出来,于是百度题解。然而搜到的题解,要不看得艰难,要不一看就是200行以上的,就可能是畏难吧,于是我甚至看题解,看别人的代码都看不下去了...
      
      但是我又实在不想放弃,接着搜搜搜,居然在百度的比较靠后的页里,找到了一份对我而言,最简洁易懂的代码,马上就理解了,于是自己借用思路手敲了一次
      
      BTW,这个博主写的真心是好,毫无冗余,并且条理逻辑十分清晰,虽然注释不多,但还是让人一眼就看懂了,真的强烈推荐大家去瞻仰一下
      http://blog.csdn.net/fzl1941572592/article/details/75208834
      
      但是值得一提的是,如果用这种写法,对格式的控制必须十分精细,不得有丝毫错漏,否则很容易WA,建议先把所有输入数据赋值到一个txt里,观察格式,末尾有无空格,还是只是换行?合理运用getchar(),必要时可以用 cout / printf 输出来检验自己的输入格式,是否真的控制好了。
      
      还要说一下,如果选手在0和1间不断变换,可以用异或符号 ^=
      
      0826更新--
      今天我自己按照博主的思路敲了一次,才发现这题,黑白棋连子的判断和替换,选手的替换,这两个最大的难点,博主都用了十分简洁清晰的思路写出来了,真是十分佩服,要是我自己写,肯定得写得很长很长很麻烦
    */


    #include <iostream>
    #include <cstring>
    #include <cstdio>
    using namespace std;
    char chess[10][10];
    typedef pair<int, int > p;
    p store[50]; 
    int dxy[8][2] = { {1, 0}, {-1, 0}, {0, 1}, {0, -1}, {-1, -1}, {-1, 1}, {1, -1}, {1, 1} };
    //#define debug
    
    void count()
    {
    	int s1 = 0, s2 = 0;
    	for (int i = 1; i <= 8; i++)
    	for (int j = 1; j <= 8; j++)
    	{
    		switch (chess[i][j])
    		{
    			case 'B': s1++; break;
    			case 'W': s2++; break;
    		}
    	}
    	printf("Black - %2d White - %2d
    ", s1, s2);
    }
    
    int is_legal(char c)
    {
    	int res = 0;
    	memset(store, 0, sizeof (store));
    	
    	for (int i = 1; i <= 8; i++)
    	{
    		for (int j = 1; j <= 8; j++)
    		{
    			bool flag = false;
    			if (chess[i][j] == '-') //在此放己方棋子作为起点
    			{
    				for (int k = 0; k < 8; k++)
    				{
    					int xx = i + dxy[k][0], yy = j + dxy[k][1]; 
    					if (xx >= 1&& xx <= 8 && yy >= 1 && yy <= 8 && chess[xx][yy] != c && chess[xx][yy] != '-') //只要该方向上距离 chess[i][j]最近的位置满足这个严苛的条件,就可以一直往这个方向循环,直到越界,或者因为不满足特定条件而break出来 
    					{
    						while (xx >= 1&& xx <= 8 && yy >= 1 && yy <= 8) //在此方向不断延伸,直到碰到己方棋子,或空位,
    						{
    							xx += dxy[k][0]; yy += dxy[k][1];
    							
    							if (chess[xx][yy] == '-') break; // 夹住对方棋子的条件:两端都是己方棋子,不能是空位
    							if (chess[xx][yy] != c) continue; // 如果是对方棋子,继续循环
    							
    							flag = true; break; //如果是己方棋子,标记一下这个起点(i,j)可以放置,于是就可以退出了,将这个位置赋值pair数组
    						}
    					}
    				}
    			}
    			
    			if (flag)
    			{
    				res++;
    				store[res].first = i; store[res].second = j;
    			}
    		}
    	}
    	return res;
    }
    
    void change (int x, int y, char c)
    {
    	chess[x][y] = c;
    	for (int i = 0; i < 8; i++)
    	{
    		int xx = x + dxy[i][0], yy = y + dxy[i][1];
    		bool flag = false;
    		
    		if (xx >= 1 && xx <= 8 && yy >= 1 && yy <= 8 && chess[xx][yy] != c && chess[xx][yy] != '-') //注意,有2个x的变量,有2个y的变量,不要写漏为1个了,我在这个地方WA了几次,找了很久,真的很难发现 
    		{
    			while (xx >= 1&& xx <= 8 && yy >= 1 && yy <= 8)
    			{
    				xx += dxy[i][0]; yy += dxy[i][1];
    							
    				if (chess[xx][yy] == '-') break;
    				if (chess[xx][yy] != c) continue;
    							
    				flag = true; break; //确认当前方向的确可以替换己方棋子
    			}
    		}
    		
    		if (flag)
    		{
    			xx = x + dxy[i][0]; yy = y + dxy[i][1];
    			while (xx >= 1&& xx <= 8 && yy >= 1 && yy <= 8)
    			{
    				chess[xx][yy] = c;
    				xx += dxy[i][0]; yy += dxy[i][1];
    				
    				if (chess[xx][yy] == c) break; // 等到遇到己方棋子,该方向的替换也就结束了
    			}
    		}
    		
    	}
    }
    
    void showchess()
    {
    	for (int i = 1; i <= 8; i++)
    	{
    		for (int j = 1; j <= 8; j++) cout << chess[i][j];
    		cout << endl;
    	}
    }
    
    int main()
    {	
    	#ifdef debug
    	freopen("E:\in.txt", "r", stdin);
    	freopen("E:\out.txt", "w", stdout);
    	#endif
    	int t, kase = 0, s; //s表示当前棋局从谁开始下 
    	char player[2] = { 'W', 'B' };
    	char start, order; //起始选手,指令 
    	cin >> t;
    	getchar(); //处理末尾的回车符 
    	while (t--)
    	{
    		if (kase++) cout << endl;
    		for (int i = 1; i <= 8; i++)
    		{
    			for (int j = 1; j <= 8; j++)
    			cin >> chess[i][j];
    			getchar(); //处理末尾的回车符 
    		}
    		
    		cin >> start; getchar(); //处理回车
    		if (start == 'W')s = 0; else s = 1;
    		
    		while (cin >> order)
    		{
    			if (order == 'Q')
    			{
    				showchess();
    				getchar();
    				break;
    			}
    			else if (order == 'M')
    			{
    				int r, c, rc; // row, colunm
    				cin >> rc;
    				r = rc / 10;
    				c = rc % 10;
    				if (is_legal(player[s]))
    				change(r, c, player[s]);
    				else
    				{
    					s ^= 1;
    					change(r, c, player[s]);
    				}
    				s ^= 1; //别忘了为M时,是真正的两人下棋的情况,一定要记得一人下完以后,更换选手了!!! 
    				count();
    			}
    			else
    			{
    				int ans = is_legal(player[s]);
    				
    				if (!ans) cout << "No legal move." << endl;
    				else
    				{
    					printf("(%d,%d)", store[1].first, store[1].second);
    					
    					for (int i = 2; i <= ans; i++)
    					printf(" (%d,%d)", store[i].first, store[i].second);
    					
    					cout << endl;
    				}
    			}
    			getchar();
    		}			
    	}	
    	#ifdef debug
    	fclose(stdin);
    	fclose(stdout);
    	#endif
    	return 0;
    }



  • 相关阅读:
    nodeName,nodeValue未知 xml 入库方案 The ElementTree iterparse Function
    如何:执行大型 XML 文档的流式转换 大XML文件解析入库的一个方法
    python curl_get-pip.py Installing with get-pip.py
    iptables List the rules in a chain or all chains
    goroutine 分析 协程的调度和执行顺序 并发写 run in the same address space 内存地址 闭包 存在两种并发 确定性 非确定性的 Go 的协程和通道理所当然的支持确定性的并发方式(
    数据库业界
    The MEAN stack is a modern replacement for the LAMP (Linux, Apache, MySQL, PHP/Python) stack
    Using Groovy To Import XML Into MongoDB
    虚拟机网络模式 桥接 网桥 交换机
    防止有内存泄漏并尽可能快地释放所有内存是内存管理的重要组成部分 长时间运行进程的内存泄漏
  • 原文地址:https://www.cnblogs.com/mofushaohua/p/7789495.html
Copyright © 2011-2022 走看看