华为在线软件训练与测试

1 hashcode

求字符串的hash值
描述:

对于形如abcd...n的字符串,求字符串散列值((((a*31 + b) * 31 + c) * 31)+...)*31 + n

运行时间限制: 无限制
内存限制: 无限制
输入:

字符串,如abcd

输出:

字符串对应的hashcode值,是一个整数

样例输入:
abc
样例输出:
96354
答案提示:

hashcode可能超过32位整数最大值,考虑使用64位整数

PS:测试结果为答案错误,还未找到原因。
#include <iostream>
#include <string>
using namespace std;

int main()
{
     string str;
     cin >> str;
     long long hashcode = str[0];

     int i;
     for(i = 1; i < str.size(); i++)
     {
          hashcode = hashcode*31+str[i];
     }
     if(str.size() == 0)
     {
          cout << 0 << endl;
     }
     else
     {
          cout << hashcode << endl;
     }
     system("pause");
     return 0;
}


 

 

2、单词迷宫

 Word Maze 是一个网络小游戏,你需要找到以字母标注的食物,但要求以给定单词字母的顺序吃掉。如上图,假设给定单词if,你必须先吃掉i然后才能吃掉f。


    但现在你的任务可没有这么简单,你现在处于一个迷宫Maze(n×m的矩阵)当中,里面到处都是以字母标注的食物,但你只能吃掉能连成给定单词W的食物。


如下图,指定W为“SOLO”,则在地图中红色标注了单词“SOLO”。 

 

注意区分英文字母大小写,你只能上下左右行走。

运行时间限制: 无限制
内存限制: 无限制
输入:

输入第一行包含两个整数n、m(0<n, m<21)分别表示n行m列的矩阵,第二行是长度不超过100的单词W,从第3行到底n+3行是只包含大小写英文字母的长度为m的字符串。

输出:

如果能在地图中连成给定的单词,则输出“YES”,否则输出“NO”。注意:每个字母只能用一次。

样例输入:
5 5
SOLO
CPUCY
EKLQH
CRSOL
EKLQO
PGRBC
样例输出:
YES

#include <iostream>   
#include <vector>   
#include <string>   
using namespace std;  
  
const int MAX = 30;  
int N, M;  
string sGoal;		// 待匹配字符串  
struct Node  
{  
     int row;  
     int col;  
};  
  
char chess[MAX][MAX];  // 记录单词迷宫
bool visit[MAX][MAX];  // visit[i][j] = true表示[i][j]是否已经走过,
bool ava[MAX][MAX];		// ava[i][j] = true表示[i][j]在单词迷宫内
						// ava[i][j] = false表示[i][j]已经越界
vector<Node> vec;		// 储存符合待匹配字符串起始字符的位置
  
int r[] = {-1, 0, 1, 0};  
int c[] = {0, -1, 0, 1};  
  
// row: 迷宫横坐标 col:迷宫纵坐标 index:已经搜索到符合要求的字符串长度 length:待匹配字符串长度
bool DFS(int row, int col, int index, int length)  
{  
     if(index == length)	// 已经在迷宫内搜索到符合要求的字符串
     {  
          return true;  
     }  
  
     int i;  
     for(i = 0; i < 4; i++)  // 0~3表示分别代表上,左,下,右四个方向进行搜索
     {  
          int rt = row + r[i];		// 根据搜索方向更新坐标
          int ct = col + c[i];  
          if(!visit[rt][ct] && ava[rt][ct] && chess[rt][ct] == sGoal[index])	// 判断更新后状态是否满足要求
          {  
               visit[rt][ct] = true;  
               if( DFS( rt, ct, index+1, length) )  // DFS
               {  
                    return true;  
               }  
               visit[rt][ct] = false;  
          }  
     }  
     return false;  
}  
                
int main()  
{  
     cin >> N >> M;  
     cin >> sGoal;  
     int i,j;  
     memset(visit, false, sizeof(visit));	// 初始化为false;
     memset(ava, false, sizeof(ava));  
     for(i = 1; i <= N; i++)				// 输入单词迷宫
     {  
          for(j = 1; j <= M; j++)  
          {  
               char cTemp;  
               cin >> cTemp;  
               chess[i][j] = cTemp;  
               ava[i][j] = true;			// 单词迷宫内ava[i][j]=true
               if(cTemp == sGoal[0])		// 将待匹配字符串起始字母作为DFS搜索的起点,节省时间
               {  
                    Node temp;  
                    temp.row = i;  
                    temp.col = j;  
                    vec.push_back(temp);  
               }  
          }  
     }  
  
     bool flag = false;			// flag = false表示在单词迷宫内没有搜索到待匹配字符
     for(i = 0 ; i < vec.size(); i++)  
     {  
          if( DFS(vec[i].row, vec[i].col, 1, sGoal.size()) )  
          {  
               cout << "YES" << endl;  
               flag = true;  
               break;  
          }  
     }  
  
     if(!flag)  
     {  
          cout << "NO" << endl;  
     }  
  
     return 0;  
}  




3、计算麻将番数

(样题,已对外公布)计算麻将的番数
描述:

计算麻将的番数

麻将游戏越来越受到大家喜爱,也在网络上盛行。本题目是给定一组已经和牌的麻将,编写一个函数计算这组麻将的番数。为简化题目,假设麻将只有筒子和条子两种花型,能翻番的规则也只有以下三种,当一组牌中没有下述三种情况中的一种或多种,则这组牌为0番,每种番数是加的关系,例如一组牌既有卡2条又有四归一,则番数为3番。

1.2条为一番,即有一局牌是 123条;

2.四归一为两番,即有4张一样的牌(花色和数字都一样);

3.巧七对为两番,即一组牌恰好是7对牌;

  一些约定:

1.一组已经和牌的麻将由多局牌组成,一局牌可以是一对牌、3张连续同样花色的牌、3张一样的牌、4张一样的牌。

2.一组已经和牌一般有14张牌,最多可以有18张牌(当有四归一的时候)

 

运行时间限制: 无限制
内存限制: 无限制
输入:

一字符串表示已经和牌的麻将(由输入者保证,编程人员无需考虑没有和牌),如1T2T3T,4T5T6T,7T8T9T,1D2D3D,4D4D.

说明:

1.”1T”表示1条,T表示条子,前面跟数字几表示几条,数据范围19,输入者保证,编程无需考虑输入规范性;

     2.”4D”表示4筒,D表示筒子,前面跟数字几表示几筒,数据范围是19, 输入者保证,编程无需考虑输入规范性;

     3.每局牌之间由’,’隔开,输入者保证每局牌都是正确的且按照数字由小到大排序,编程人员无需判断每局牌的正确性;

     4.一组牌以’.’号结束,由输入者保证,编程人员无需考虑是否有”.”号。

   5.输入保证有番数的牌在一局中,编程人员无需考虑排序,即有番数的牌不会分散在多局牌中。

 

输出:

麻将的番数,整型类型。

 

样例输入:
1T2T3T,4T5T6T,7T8T9T,1D2D3D,4D4D.
样例输出:
1
答案提示:

只输出番数,且为整型。

 

#pragma warning(disable:4786)
#include <map>
#include <iostream>
#include <vector>
#include <string>
using namespace std;

vector<string> vec;        // 保存每一局的牌
map<string, int> m;        // 保存每一局的对数

int main()
{
   string str;            // 一组牌
   cin >> str;
   string::size_type pos = str.find(',');
   string sTemp(str.begin(), str.begin()+pos);
   vec.push_back(sTemp);

   while(pos != string::npos)
   {
       string::size_type pos_temp = pos;
       pos = str.find(',', pos+1);
       string sTemp;
       if( pos != string::npos)
       {
           sTemp.assign(str.begin()+pos_temp+1, str.begin()+pos);
       }
       else
       {
           sTemp.assign(str.begin()+pos_temp+1, str.end()-1);
       }
       vec.push_back(sTemp);
   }

   int i,j;
   int count = 0;        // 番数
   int number = 0;        // 对数

   string s1("1T2T3T");
   int step;        // 当step == 4,即当局牌里有四归一
   for(i = 0; i < vec.size(); i++)
   {
       if( vec[i] == s1 )    // 卡2条
       {
           count++;
           continue;
       }
       m.clear();
       string str1;
       step = 1;
       
       for(j = 0; j < vec[i].size(); j += 2)    // 保存每一局里的对子数
       {
           string stemp(vec[i].begin()+j, vec[i].begin()+j+2);
           if( stemp == str1 )
           {
               step++;
           }
           m[stemp]++;
           str1 = stemp;
       }
       map<string, int>::iterator mit = m.begin();    // 统计每一局里的对子数
       for(; mit != m.end(); mit++)
       {
           if( mit->second > 1 )
           {
               number += (mit->second/2);
           }
       }
       if(step == 4)    // 四归一
       {
           count += 2;
       }
   }
   if(number == 7)        //巧七对
   {
       count += 2;
   }

   cout << count << endl;
   return 0;
}  



评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值