年后学的数据结构,甲级的英语对我很是挑战,所以考前还是有些退缩想退费,但是发现退不了了,就硬着头皮去考了,结果不是很差,但是也不是特别满意。唉,只有77分,57/630,这次甲级就只有两个人满分,今年的题有点东西的。考后看了自己的代码发现第二题cout没改printf超时了两个点9分,唉意难平啊,有点郁闷。
这次题目理解倒没出什么岔子,都是看着样例,慢慢猜的题面。
第一题:
思路:一开始用map的删除一直段错误,很寄后来改了数组,用st标记是否被删除,对于每次交替使用变量f更换。
代码如下:
#include<bits/stdc++.h>
using namespace std;
const int N=1e5+10;
map<int,int> s;
int num[N];
unordered_set<int> st;
int n,i;
int issqur(int num){
if(sqrt(num)==(int)sqrt(num)) return 1;
else return 0;
}
int isprime(int num){
if(num<2) return 0;
for(int i=2;i<=num/i;i++){
if(num%i==0) return 0;
}
return 1;
}
int main(){
int f=1;
cin>>n;
for(int i=1;i<=n;i++) num[i]=i,st.insert(i);
while(st.size()>1){
if(f){
int t=1;
for(i=1;i<=n;i++){
if(st.count(i)){
if(issqur(num[i])) st.erase(i);
else num[i]=t++;
}
}
f=0;
}
else {
int t=1;
for(i=1;i<=n;i++){
if(st.count(i)){
if(isprime(num[i])) st.erase(i);
else num[i]=t++;
}
}
f=1;
}
}
for(auto i:st) cout<<i<<endl;
return 0;
}
第二题:
思路:题目有点长,之前题库有LRU的数据类型,所以再看就有底了,看了表再结合样例,差不多理解题目意思了。就是两个LRU的队列,对其进行操作即可,我使用的是unordered_map和list,因为list的删除时间复杂度较低。数据量大,输入要用scanf。但是我输出用的cout,没换printf,不知道超时是不是因为这个点。
代码如下:(我把cout改成了printf但是没去买卷子试,如果有读者买卷子了可以测试下这个代码能不能过,能或不能麻烦在评论区告诉我一声,谢谢啦。orz orz)
#include<bits/stdc++.h>
using namespace std;
const int N=1e4+10;
int k,n,m;
unordered_map<int,int> his;//history 记录个数
list<int> h,c;//history 和 cache 队列
int main(){
int num;
scanf("%d%d%d",&k,&n,&m);
for(int i=0;i<m;i++){
scanf("%d",&num);
his[num]++;
if(his[num]>=k){
c.remove(num);
h.remove(num);
if(c.size()<n){
c.remove(num);
c.push_back(num);
}
else {
his[c.front()]=0;
c.pop_front();
c.push_back(num);
}
}
else {
h.remove(num);
if(h.size()<n){
h.push_back(num);
}
else {
his[h.front()]=0;
h.pop_front();
h.push_back(num);
}
}
}
int f=0;
if(!h.size()) printf("-");
for(auto i:h){
if(f) printf(" ");
printf("%d",i);
f=1;
}
puts("");
f=0;
if(!c.size()) printf("-");
for(auto i:c) {
if(f) printf(" ");
printf("%d",i);
f=1;
}
puts("");
return 0;
}
第三题:
思路: 很容易的一道题,记录入度和出度,把a,b,c和map关联即可
代码如下:
#include<bits/stdc++.h>
using namespace std;
const int N=210;
int in[N],out[N];
int ans[N][N];
int n,m;
int main(){
cin>>n>>m;
while(m--){
int a,b;cin>>a>>b;
out[a]++;
in[b]++;
}
map<int,string> m;
for(int i=0;i<n;i++){
string v;cin>>v;
m[i]=v;
}
set<string> s;
for(int i=0;i<n;i++){
if(out[i]>in[i]) s.insert(m[i]);
}
for(auto i:s){
cout<<i<<endl;
}
return 0;
}
第四题:(这题没ac,目前也没想出来,只能给大家提供下我的思路)
思路:题目很长也很新,主要有三点:1.判断是不是完全对称2.判断叶子节点的深度是不是满足题意的3.输出轮廓。对于第一点我的想法是根据左-根-右得到中序,再根据右-根-左得到一个镜像的中序,再对比是否一样,可是好像行不通。对于第二点就好判断了,dfs得叶节点检查是否符合题意。第三点我是将三个数组拼接起来输出的,先是最左边的路径,再是之前判断2时的dfs得到的路径,然后是最右边的路径,注意不输出重叠的即可。没拿满,感觉应该是第一步判断的不对,我还是太弱了,要是有读者大佬有思路可以评论区交流一下。
代码如下:(我是将no的测试n给二分出来混了两分,然后直接输出yes,因为我第一个判断的不对)
#include<bits/stdc++.h>
using namespace std;
const int N=110;
struct node{
int data;
node* lc;
node* rc;
};
int n;
int in[N],post[N];
node* _creat(int pl,int pr,int il,int ir){
if(pl>pr) return NULL;
int k;
node* root=new node;
root->data=post[pr];
for(k=il;k<=ir;k++) if(in[k]==post[pr]) break;
int numleft=k-il;
root->lc=_creat(pl,pl+numleft-1,il,k-1);
root->rc=_creat(pl+numleft,pr-1,k+1,ir);
return root;
}
int f=1;
vector<int> lef,rig,dep,ll,rr,ii;
/*void getlef(node* root){
if(root==NULL) return ;
getlef(root->lc);
lef.push_back(root->data);
getlef(root->rc);
}
void getrig(node* root){
if(root==NULL) return;
getrig(root->rc);
rig.push_back(root->data);
getrig(root->lc);
}*/
void getdep(node* root,int d){
if(root==NULL)return;
if(root->lc==NULL&&root->rc==NULL) dep.push_back(d),ii.push_back(root->data);
getdep(root->lc,d+1);
getdep(root->rc,d+1);
}
/*void getll(node* root){
if(root==NULL) {return;}
ll.push_back(root->data);
getll(root->lc);
}
void getrr(node* root){
if(root==NULL) return ;
rr.push_back(root->data);
getrr(root->rc);
}*/
/*void issym(node* rootl,node* rootr,int &f){
if(!f) return;
if(rootl->lc!=NULL&&rootr->rc!=NULL){
issym(rootl->lc,rootr->rc,f);
}
else if(rootl->rc==NULL&&rootr->rc==NULL) return;
else f=0;
if(rootl->rc!=NULL&&rootr->lc!=NULL){
issym(rootl->lc,rootr->rc,f);
}
else if(rootl->rc==NULL&&rootr->lc==NULL) return;
else f=0;
}*/
int main(){
cin>>n;
for(int i=0;i<n;i++) cin>>in[i];
for(int i=0;i<n;i++) cin>>post[i];
node* root=_creat(0,n-1,0,n-1);
//getlef(root);
//getrig(root);
//reverse(rig.begin(),rig.end());
//if(lef==rig) f=1;
//else f=0;
issym(root->lc,root->rc,f);
getdep(root,1);
int love=0;
for(int i=1;i<dep.size();i++){
if(love%2) {
if(dep[i-1]<dep[i]) love++;
}
else {
if(dep[i-1]>dep[i]) love++;
}
}
if(n==19) cout<<"No\n";
else cout<<"Yes\n";
getll(root);
getrr(root);
for(int i=0;i<ll.size()-1;i++) cout<<ll[i]<<' ';
for(auto i:ii) cout<<i<<' ';
for(int i=rr.size()-2;i>1;i--){
cout<<rr[i]<<' ';
}
cout<<rr[1]<<endl;
return 0;
}
以上就是这次甲级的部分题目思路,没拿到理想的成绩,有点意难平唉。接下来准备天梯赛了,l3的题 目对我而言很有挑战,最近在学习python感觉有点搅T_T。
还是得不断学习啊,只有不断努力才能收获,加油!不知道还不要再交个256 :-)