华为2016研发工程师编程题详解

第一题:

有一个数组a[N]顺序存放0~N-1,要求每隔两个数删掉一个数,到末尾时循环至开头继续进行,求最后一个被删掉的数的原始下标位置。以8个数(N=7)为例:{0,1,2,3,4,5,6,7},0->1->2(删除)->3->4->5(删除)->6->7->0(删除),如此循环直到最后一个数被删除。

输入描述:
每组数据为一行一个整数n(小于等于1000),为数组成员数,如果大于1000,则对a[999]进行计算。
输出描述:
一行输出最后一个被删掉的数的原始下标位置。
输入例子1:
8
输出例子1:
6

题解:
模拟。用cnt记录下标,删除的数在vis数组中置0,res记录访问的没被删除的数,res%3时删除数。当vis中只有一个1时,对应的数即为所求。
#include<algorithm>
#include<iostream>
#include<cstdio>
#include<vector>
#include<queue>
#include<set>
#include<map>
#define maxn 30035
using namespace std;
 
int main() {
    int i;
    while( cin >> i ) {
        if( i > 1000 ) {
            i = 1000;
        }
        vector<int> list;
        int vis[1050];
        for( int j = 0; j < i; j ++ ) {
            list.push_back(j);
            vis[j] = 0;
        }
        int cnt = 0, res = 0;
        while( 1 ) {
            cnt ++;
            if( !vis[cnt-1] ) {
                res ++;
            }
            if( res%3 == 0 ) {
                vis[cnt-1] = 1;
                res = 0;
            }
            int flag = 0;
            for( int j = 0; j < i; j ++ ) {
                if( vis[j] ) {
                    flag ++;
                }
            }
            if( flag == i-1 ) {
                break;
            }
            if( cnt == i ) {
                cnt = 0;
            }
        }
        for( int j = 0; j < i; j ++ ) {
            if( !vis[j] ) {
                cout << j << endl;
            }
        }
    }
    return 0;
}

  第二题:

输入一个字符串,求出该字符串包含的字符集合


输入描述:
每组数据输入一个字符串,字符串最大长度为100,且只包含字母,不可能为空串,区分大小写。

输出描述:
每组数据一行,按字符串原有的字符顺序,输出字符集合,即重复出现并靠后的字母不输出。

输入例子1:
abcqweracb

输出例子1:
abcqwer

题解:
用个vis数组记录已经出现过的字母,把第一次出现的按顺序加入vector
#include<algorithm>
#include<iostream>
#include<cstdio>
#include<vector>
#include<queue>
#include<set>
#include<map>
#define maxn 30035
using namespace std;
int main() {
    string str;
    while( cin >> str ) {
        vector<char> ans;
        int vis[100] = {0};
        for( int i = 0, len = str.length(); i < len; i ++ ) {
            if( str[i] >= 'a' && str[i] <= 'z' ) {
                if( !vis[str[i]-'a'] ) {
                    vis[str[i]-'a'] = 1;
                    ans.push_back(str[i]);
                }
            } else {
                if( !vis[(str[i]-'A')+30] ) {
                    vis[(str[i]-'A')+30] = 1;
                    ans.push_back(str[i]);
                }
            }
        }
        for( char c : ans ) {
            cout << c;
        }
        cout << endl;
    }
    return 0;
}

  第三题:

数独是一个我们都非常熟悉的经典游戏,运用计算机我们可以很快地解开数独难题,现在有一些简单的数独题目,请编写一个程序求解。
如有多解,输出一个解

输入描述:
输入9行,每行为空格隔开的9个数字,为0的地方就是需要填充的。

输出描述:
输出九行,每行九个空格隔开的数字,为解出的答案。

题解:
从第一个需要填数字的位置开始搜索,每次搜索的方向是当前位置的下一个需要填的位置。细节看代码。
答案有多解,牛客网的样例没有覆盖全部情况,这份代码只过了三组样例。
#include<algorithm>
#include<iostream>
#include<cstdio>
#include<vector>
#include<queue>
#include<set>
#include<map>
#define maxn 30035
using namespace std;
int mp[15][15];
int f( int x, int y, int z ) {
	for( int i = 1; i <= 9; i ++ ) {
		if( i != y ) {
			if( mp[x][i] == z ) {
				return 0;
			}
		}
	} 
	for( int i = 1; i <= 9; i ++ ) {
		if( i != x ) {
			if( mp[i][y] == z ) {
				return 0;
			}
		}
	}
	int sx, ex, sy, ey;
	if( x >= 1 && x <= 3 ) {
		sx = 1, ex = 3;
	} else if( x >= 4 && x <= 6 ) {
		sx = 4, ex = 6;
	} else {
		sx = 7, ex = 9;
	}
	if( y >= 1 && y <= 3 ) {
		sy = 1, ey = 3;
	} else if( y >= 4 && y <= 6 ) {
		sy = 4, ey = 6;
	} else {
		sy = 7, ey = 9;
	}
	for( int i = sx; i <= ex; i ++ ) {
		for( int j = sy; j <= ey; j ++ ) {
			if( i == x && j == y ) {
				continue;
			}
			if( mp[i][j] == z ) {
				return 0;
			}
		}
	}
	return 1;
}
pair<int,int> next( int x, int y ) { //找x,y后下一个需要填的位置 
	for( int i = x; i <= 9; i ++ ) {
		for( int j = 1; j <= 9; j ++ ) {
			if( i == x && j <= y ) {
				continue;
			}
			if( !mp[i][j] ) {
				return make_pair(i,j);
			}
		}
	}
}
int dfs( int x, int y ) {
	for( int i = 1; i <= 9; i ++ ) {
		if( f(x,y,i) ) { //判断当前填的数字是否符合规则 
			mp[x][y] = i;
			if( x == 9 && y == 9 ) { 
				return 1;
			}
			pair<int,int> node = next(x,y);
			if( dfs(node.first,node.second) ) { //若后面的都可以,说明可填i 
				return 1;
			}
			mp[x][y] = 0; //填i不能满足后面,重置为0 
		}
	}
	return 0;
}
int main() {
	for( int i = 1; i <= 9; i ++ ) {
		for( int j = 1; j <= 9; j ++ ) {
			cin >> mp[i][j];
		}
	}
	if( !mp[1][1] ) {
		dfs(1,1);
	} else {
		pair<int,int> node = next(1,1);
		dfs(node.first,node.second);
	}
	for( int i = 1; i <= 9; i ++ ) {
		for( int j = 1; j <= 9; j ++ ) {
			if( j == 9 ) {
				cout << mp[i][j] << endl;
			} else {
				cout << mp[i][j] << " ";
			}
//			cout << "i:" << i << " j:" << j << " next:(" << next(i,j).first << "," << next(i,j).second << ")" << endl;
		}
	}
    return 0;
}

/** 样例 
8 0 0 0 0 0 0 0 0
0 0 3 6 0 0 0 0 0
0 7 0 0 9 0 2 0 0
0 5 0 0 0 7 0 0 0
0 0 0 0 4 5 7 0 0
0 0 0 1 0 0 0 3 0
0 0 1 0 0 0 0 6 8
0 0 8 5 0 0 0 1 0
0 9 0 0 0 0 4 0 0

7 2 6 9 0 4 0 5 1
0 8 0 6 0 7 4 3 2
3 4 1 0 8 5 0 0 9
0 5 2 4 6 8 0 0 7
0 3 7 0 0 0 6 8 0
0 9 0 0 0 3 0 1 0
0 0 0 0 0 0 0 0 0
9 0 0 0 2 1 5 0 0
8 0 0 3 0 0 0 0 0
**/

  

彼时当年少,莫负好时光。
原文地址:https://www.cnblogs.com/l609929321/p/14981930.html