//求大小为10的数组中不重复的元素个数(不用bool数组的解法)
sort(a,a+10);
for(int i = 1;i<a.size();i++)
{
if(a[i] != a[i-1])
sum++;
}
UVA101题
1.先输入int型 后输入string型的题目,输入int后要有getchar
2.注意第一步返回ret1=0 说明此情况为特例,应立即break
{int ret1 = analyse();
if(!ret1)
break;
int ret2 = findab();
if(!ret2)
continue;
}
3.图为利用find与substr切割字符串的解法,附带stringstream的使用
pos = 0;
stringstream t1,t2;
tempNum = temp.find(' ',pos);
tempF = temp.substr(pos,tempNum - pos);
pos = tempNum + 1;
tempNum = temp.find(' ',pos);
t1 << (temp.substr(tempNum - pos));
t1 >> a;
pos = tempNum + 1;
tempNum = temp.find(' ',pos);
tempS = temp.substr(pos,tempNum - pos);
pos = tempNum + 1;
t2 << temp.substr(pos,temp.size()-pos);
t2 >> b;
4.图下的方式(接3)能省去先输入后切割还要分析的麻烦(挨个输入)
while (cin >> Com1)
{
if (Com1 == "quit")
break;
string Com2;
int a, b;
cin >> a >> Com2 >> b;
if (poss[a].x == poss[b].x)
continue;
if (Com1 == "move")
MoveBack(a);
if (Com2 == "onto")
MoveBack(b);
MoveAll(a, b);
}
5.可以在建立vector数组的同时,建立一个速查表,以struct node为元素,每次更改vector后更新速查表元素。
vector的resize函数可以迅速切断vector后面一段的元素
blocks[local.x].resize(local.y + 1);//重置大小(删除方块堆后面的方块)
1.关于链表:
迅速找到中间节点:快慢指针,一个指针一次走一步,一个指针一次走两步。
UVA11988
STL中链表为list
可以使用迭代器iterator=list.begin()|end()来控制输入符在begin还是end
(我的做法,设计两个string,‘【’开始向temp输入 ‘】’开始讲temp回归到all的最前端)
UVA12657
1.遇到问题:将一个数移到另一个数左边,使用迭代器的话,删除元素可能会使迭代器移动,因为迭代器无法比较大小,所以不稳定,不知道什么时候移动什么时候不移动
可以采用静态链表&&双向链表,查找元素为O(1)的复杂度,设置pre和nxt两个数组
2.翻转链表可以不急着动,只要标记状态即可,比如说现在是翻转状态的将a放到b左边,即放到右边即可,逻辑顺序不会变,最后统一对不同状态讨论,题目让求奇数和,则顺序奇数和或逆序奇数和。
3.设置头结点和尾结点,不能只设置头结点不设置尾结点,不然翻转的话尾结点就变成了头结点,要对称。
4.求奇数位的和,和偶数位的和,可以用总和减,免去循环。
UVA514
注意,栈等stl的调用,比如top函数,必须在栈中有元素的前提下才可以进行
即
if(!src.empty())
{
if(squl[cnt] == src.top())
{
cnt++;
src.pop();
continue;
}
}
有先后顺序
如果直接
if(!src.empty()&&squl[cnt] == src.top)
会报错(不过有短路原理应该也可,没试)
UVA442
关于栈
注意谁先出谁后出
mtx temp2 = allStack.top();
allStack.pop();
mtx temp1 = allStack.top();
allStack.pop();
还有,用字母作下标表示的数组
不用alpha2int函数来转换,直接减去‘A’或‘a’即可
还有 有时候考虑的太多了,题目没有那么多情况。
UVA12100
牺牲空间换时间做法:
//bool curIsMax()//当前的是否是最大的,是否可以执行?
//{
// int cur = que[0].num;
// for(int i = 1;i < que.size();i++)
// {
// if(cur < que[i].num)
// {
// return false;
// }
// }
// return true;
//}
我的做法↑普通遍历找最大
老师的做法↓
复制初始数组
a.pushback(intputNum);
b.pushback(intputNum);
sort(b.begin(),b.end(),greater<int>());//不写函数默认升序。
int w = 0;
b[w++]即为最大值
unique函数去重
使用方法(一般为先排序后去重)
unique函数返回尾地址。
sort(arr,arr+n);
int n2 = unique(arr,arr+n)-arr;
for(int i = 0;i<n2;i++)
{
cout << arr[i] << ' ';
}
如何存储如下的数据?
0001000
0001000
0001111
0001000
0001000
0001000
1111111
n*n的矩阵,n未知?
string arr[205];//字符串数组
第一行特殊存储
cin >> arr[0];
for(int i = 1;i < arr[0].size();i++)
{
cin >> arr[i];
}
即可
P1830
用一个二维数组存储两个点坐标,不如用一维数组,分开存储即可。
有些不用二维数组的。
要求:存储每个点被轰炸次数:
二维数组arr[105][105]
数组中存储的数代表被轰炸次数。
不如:
4个一维数组存储每次轰炸的左上和右下顶点坐标
for(int i = 1;i <= x;i++)
{
cin >> arrx1[i] >> arry1[i] >> arrx2[i] >> arry2[i];
}
之后
if(tempx >= arrx1[j] && tempx <= arrx2[j] && tempy >= arry1[j] && tempy <= arry2[j])
{
cnt++;
times = j;
}//关键代码
在输入被检测坐标的时候根据四个一维数组来判断轰炸次数。
关于kmp
求next数组
其实是求之前的元素最多的前缀等于后缀,和这个字符本身无关。
以下是模式匹配出所有情况。
string s1,s2;
cin >> s1 >> s2;
string::size_type pos = 0;
while((pos = s1.find(s2,pos))!=string::npos)
{
cout << pos+1 << endl;
pos++;
}
UVA401
一个特别奇妙的方法:
记录每个字母与数字的镜像数
不再需要键值对map 这个stl
直接用string
string str = "A 3 HIL JM O 2TUVWXY51SE Z 8 "
检测两个字符是否匹配↓
if(isupper(c))
{
if(str[c-'A'] == d)
return true;
else
return false;
}
else
{
if(str[c-'0'+25] == d)
return true;
else
return false;
}