第一题:
有一个数组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
**/