点击查看题目描述
该题运用了散列表的思想对数据进行存储
散列表(Hash table,也叫哈希表),是根据键(Key)而直接访问在内存存储位置的数据结构。也就是说,它通过计算一个关于键值的函数,将所需查询的数据映射到表中一个位置来访问记录,这加快了查找速度。这个映射函数称做散列函数,存放记录的数组称做散列表。 ——维基百科
#include
using namespace std;
struct node{
int guodao;
int count;
};
node a[2500]={},b[2500]={};//初始化,变量全为0
inline int cmp2(node n1,node n2){
return n1.guodao<n2.guodao;
}
bool cmp(node x,node y)
{
return x.count>y.count;
}
int main()
{
int M,N,K,L,D;//分别代表教室有M行N列
cin>>M>>N>>K>>L>>D;//K条横向通道,L条纵向通道;D对讲话的同学
int cntl,cntk;
int e=0,f=0;
for(int i=0;i<D;i++)
{
int x1,x2,y1,y2;
cin>>x1>>y1>>x2>>y2;
if(x1==x2) //如果横坐标相等,则选择纵轴偏小的作为过道
{
cntl=(y1<y2)?y1:y2;
b[cntl].guodao=cntl;//存储在cntl处
b[cntl].count++;
}
else if(y1==y2) //如果纵坐标相等,则选择横轴偏小的作为过道
{
cntk=(x1<x2)?x1:x2;
a[cntk].guodao=cntk; //存储在cntk处
a[cntk].count++;
}
}
//按照过道选择次数降序排列
sort(a,a+M,cmp);
sort(b,b+N,cmp);
//按照过道数字大小升序排列
sort(a,a+K,cmp2);
sort(b,b+L,cmp2);
for(int i=0;i<K;i++)
cout<<a[i].guodao<<" ";
cout<<endl;
for(int i=0;i<L;i++)
cout<<b[i].guodao<<" ";
return 0;
}
点击查看题目详情
看到题目我就想到队列,不过我是直接用数组模拟队列,而知道STL的选手们直接使用queue
以下是这两种思想的不同代码,不得不说一句STL万岁!
手动模拟:
#include
using namespace std;
bool searchin(int num,int M,int m[])
{
bool k=false;
for(int i=0;i<M;i++)
{
if(num==m[i])
{
k=true;
break;
}
}
return k;
}
int main()
{
int cnt;//计数
int M,N;
cin>>M>>N;
int m[M],n[N];
memset(m,-1,sizeof(m));
for(int i=0;i<N;i++)
{
cin>>n[i];
if(!searchin(n[i],M,m))
{
cnt++;
for(int j=1;j<M;j++)
m[j-1]=m[j];
m[M-1]=n[i];
}
}
cout<<cnt;
return 0;
}
STL:queque
#include
#include
#include
using namespace std;
queue<int>s;
int main()
{
int m,word,count=0,f[1010]={0};
cin >> m >> word;
for(int i = 0; i<word; i++)
{
int x;
cin>>x;
if(f[x]==1)continue;
else
{
if(s.size()>=m)
{
f[s.front()]=0;
s.pop();//队头弹出
}
s.push(x);//队尾插入
f[x]=1;
count++;
}
}
cout<<count;
}
其中G题十分简单,但是对精度要求特别高,特此记下PI的高精度表示方式
另外输出格式上三种常见的方法
题目描述:
小雨有一个 n×n的矩阵,起点在(1,1),终点在(n,n),只能向下或向右走,且每次只能走 1 步。矩阵上每个点都有一个点权 a i , j a_{i,j} ai,j。
求走到终点的路径有多少不同的点权和。
输入描述:
第一行,输入一个正整数 n 。接下来 n+1 行,每行 n 个数,表示 a i , j a_{i,j} ai,j。
备注:1<=n<=8 ,0<= a i , j a_{i,j} ai,j<=50
输出描述:
共一行,输出有多少种不同的点权和。
示例1:
输入:
2
1 5
2 4
输出:
2
说明:
(1,1)→(2,1)→(2,2):和为7。(1,1)→(1,2)→(2,2):和为10。
这是一道典型的DFS简单题,直接套模板就能行。
其中有一个关键点用到了STL里的set容器:
set(集合):描述一个控制变长元素序列的对象。包含了经过排序了的数据,这些数据的值(value)必须是唯一的。
所以题中要求不同的点权和,用set存储就十分方便,不用去判断是否唯一。
#include
using namespace std;
long long a[MAXN][MAXN];
int n;
set<int> s;
void dfs(int x,int y,int sum){
if(x==n && y==n){
s.insert(sum); //走到(n,n)则把sum插入集合s
return;
}
if(x+1<=n){
dfs(x+1,y,sum+a[x+1][y]);//向下走
}
if(y+1<=n){
dfs(x,y+1,sum+a[x][y+1]);//向右走
}
}
int main() {
cin>>n;
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
cin>>a[i][j]; //录入矩阵
}
}
dfs(1,1,a[1][1]); //开始深搜
cout<<s.size()<<endl;//输出集合s的大小
return 0;
}
补充:
容器(Container)的概念的出现早于模板(template),它原本是一个计算机科学领域中的一个重要概念,但在这里,它的概念和STL混合在一起了。
下面是在STL中出现的7种容器:
vector(向量)——STL中标准而安全的数组。只能在vector 的“前面”增加数据。
deque(双端队列double-ended queue)——在功能上和vector相似,但是可以在前后两端向其中添加数据。
list(列表)——游标一次只可以移动一步。如果你对链表已经很熟悉,那么STL中的list则是一个双向链表(每个节点有指向前驱和指向后继的两个指针)。
set(集合)——包含了经过排序了的数据,这些数据的值(value)必须是唯一的。
map(映射)——经过排序了的二元组的集合,map中的每个元素都是由两个值组成,其中的key(键值,一个map中的键值必须是唯一的)是在排序 或搜索时使用,它的值可以在容器中重新获取;而另一个值是该元素关联的数值。比如,除了可以ar[43] = "overripe"这样找到一个数据,map还可以通过ar[“banana”] = "overripe"这样的方法找到一个数据。如果你想获得其中的元素信息,通过输入元素的全名就可以轻松实现。
multiset(多重集)——和集合(set)相似,然而其中的值不要求必须是唯一的(即可以有重复)。
multimap(多重映射)——和映射(map)相似,然而其中的键值不要求必须是唯一的(即可以有重复)。