1017 Queueing at Bank
大概题意:
n个人来办业务给出到达时间和办理时长以及窗口数量,求最短平均等待时间。
刚开始的时候,理解成简单的最短作业优先算法,每一次调度最短作业进入窗口服务。但是后来想想自己真是智障啊,银行办理业务总不能插队办理吧。所以一定是在到来时间的基础上,根据服务时间进行优先。
错误代码:
#include
using namespace std;
const int open=8*60*60;
const int close=17*60*60;
struct cost{
int s;
int serve;
bool operator < (const cost b)const{
if(s!=b.s) return s>b.s;
return serve>b.serve;
}
};
priority_queue<cost> c;
priority_queue<int, vector<int>, greater<int> > win;//升序
int main(){//平均等待时间最短 最短作业优先
int n,k,waiting=0;
scanf("%d%d",&n,&k);
for(int i=0;i<n;i++){
int hh,mm,ss,w;
scanf("%d:%d:%d%d",&hh,&mm,&ss,&w);
cost t;
t.s=hh*3600+mm*60+ss;
if(t.s<open){
waiting+=(open-t.s);
t.s=open;
}
//t.e=t.s+w*60;
t.serve=w*60;
if(t.s<=close){//下班之后来的删掉
c.push(t);
}
}
n=c.size();
while(win.size()!=k){//窗口不够对于前三个top可以建立新的窗口
win.push(open);
}
while(!c.empty()){
while(win.top()>c.top().s){//如果当前任何一个作业都无法开始 把窗口更新到最早可以开始作业 但是在这里相当于完全打乱等待队列
waiting+=(win.top()-c.top().s);
//printf("%d! ",win.top());
cost t;
t=c.top();
t.s=win.top();
c.pop();
c.push(t);
}
if(win.top()<=c.top().s) {
win.pop();
win.push(c.top().s+c.top().serve);
//printf(" !%d\n",temp);
c.pop();
}
}
//printf("%d\n%d\n",waiting,n);
if(n==0) printf("0.0\n");
else printf("%.1lf\n",waiting*1.0/(n*60));
}
所以一定不能打乱到来顺序啊气死我了!
正确代码:
#include
using namespace std;
const int open=8*60*60;
const int close=17*60*60;
struct cost{
int s;
int serve;
bool operator < (const cost b)const{
if(s!=b.s) return s>b.s;
return serve>b.serve;
}
};
priority_queue<cost> c;
priority_queue<int, vector<int>, greater<int> > win;//升序
int main(){//平均等待时间最短 最短作业优先
int n,k,waiting=0;
scanf("%d%d",&n,&k);
for(int i=0;i<n;i++){
int hh,mm,ss,w;
scanf("%d:%d:%d%d",&hh,&mm,&ss,&w);
cost t;
t.s=hh*3600+mm*60+ss;
if(t.s<open){
waiting+=(open-t.s);
t.s=open;
}
//t.e=t.s+w*60;
t.serve=w*60;
if(t.s<=close){//下班之后来的删掉
c.push(t);
}
}
n=c.size();
while(win.size()!=k){//窗口不够对于前三个top可以建立新的窗口
win.push(open);
}
while(c.size()){
cost tmp=c.top();
c.pop();
int x=win.top();
win.pop();
int stime=max(tmp.s,x);
win.push(tmp.serve+stime);
waiting+=(stime-tmp.s);
}
//printf("%d\n%d\n",waiting,n);
if(n==0) printf("0.0");
else printf("%.1lf\n",waiting*1.0/(n*60));
}
1019 General Palindromic Number
题目大意:给定一个十进制数和给定进制。求给定进制是否是回文数。
#include
using namespace std;
#define ll long long
int main(){
ll n,b;
ll a[40];
scanf("%lld%lld",&n,&b);
ll t=n;
int i=0;
while(t>=b){
a[i++]=t%b;
//printf("%d ",a[i-1]);
t/=b;
}//进制转换
a[i++]=t;
int head=0,tail=i-1;
while(head<=tail){//回文数比较
if(a[head]!=a[tail]){
printf("No\n");
for(int j=i-1;j>=0;j--){
if(j<i-1) printf(" ");
printf("%lld",a[j]);
}
return 0;
}
head++;
tail--;
}
printf("Yes\n");
for(int j=i-1;j>=0;j--){
if(j<i-1) printf(" ");
printf("%lld",a[j]);
}
return 0;
}
1020 Tree Traversals
我!终于!把树!又学了!
经常考的就是前、中、后序和层序之间的相互转换。
已知前中求后(层)、已知中后求前(层)。
洛谷上有两个差不多的题:
https://www.luogu.com.cn/problem/P1827
https://www.luogu.com.cn/problem/P1030
这个题卡了一下段错误,后来搜了一下,被卡段错的伙计们也不少。就是因为没考虑如果是个长链,也就是树它30层的情况。所以数组嘛,能往大了开就往打了开就完了。
#include
using namespace std;
int post[50],in[50];
int cnt=0;
int n;
vector<int>ll[30];
void dfs(int a,int b,int c,int d,int l){//a~b是中序串区间,c~d是后序串区间,l是递归的第几层,也就是树的第几层
if(a>b||c>d) return;
for(int i=a;i<=b;i++){
if(in[i]==post[d]){
ll[l].push_back(in[i]);
dfs(a,i-1,c,c+i-a-1,l+1);//遍历左子树,c为后序串左子树的起点,i-a-1是左子树的长度,加一起就是终点位置
dfs(i+1,b,c+i-a,d-1,l+1);//遍历右子树,同理
}
}
}
int main(){
//memset(ll,-1,sizeof(ll));
cin>>n;
for(int i=0;i<n;i++){
cin>>post[i];
}
for(int i=0;i<n;i++){
cin>>in[i];
}
dfs(0,n-1,0,n-1,0);
for(int i=0;i<30;i++){
for(int j=0;j<ll[i].size();j++){//按层输出就完事了
cnt++;
printf("%d",ll[i][j]);
if(cnt!=n) printf(" ");
}
}
cout<<endl;
return 0;
}
1022 Digital Library (30分)
选择什么样的数据结构是关键。
快速查询最先想到map。
数据量也不大,最先想到keyword那部分就直接分割存储就好。
别的部分就直接存呗。
既然书号可以作为主码,那就唯一,所以要用set,还能顺便increase一下。
怎么分呢?
//空格嘛 就这么分
getline(cin,kword);
string word;
stringstream in;
in<<kword;
while(in>>word){
keyword[word].insert(id);
}
剩下就是极其单调的CTRL+CV编程
#include
using namespace std;
map<string,set<string>>booktitle;
map<string,set<string>>writer;
map<string,set<string>>keyword;
map<string,set<string>>publisher;
map<string,set<string>>reyear;
int main(){
int n;
cin>>n;
getchar();
for(int i=0;i<n;i++){
string id,bname,wname,kword,pber,yy;
getline(cin,id);
//cout<
getline(cin,bname);
//cout<
getline(cin,wname);
getline(cin,kword);
string word;
stringstream in;
in<<kword;
while(in>>word){
keyword[word].insert(id);
}
getline(cin,pber);
getline(cin,yy);
booktitle[bname].insert(id);
writer[wname].insert(id);
publisher[pber].insert(id);
reyear[yy].insert(id);
}
cin>>n;
for(int i=0;i<n;i++){
int op;
scanf("%d: ",&op);
string ss;
getline(cin,ss);
switch(op){
case 1:{
printf("%d: ",op);
cout<<ss<<endl;
if(booktitle[ss].empty()){
cout<<"Not Found"<<endl;
}
auto it=booktitle[ss].begin();
for(it;it!=booktitle[ss].end();it++){
cout<<*it<<endl;
}
break;
}
case 2:{
printf("%d: ",op);
cout<<ss<<endl;
if(writer[ss].empty()){
cout<<"Not Found"<<endl;
}
auto it=writer[ss].begin();
for(it;it!=writer[ss].end();it++){
cout<<*it<<endl;
}
break;
}
case 3:{
printf("%d: ",op);
cout<<ss<<endl;
if(keyword[ss].empty()){
cout<<"Not Found"<<endl;
}
auto it=keyword[ss].begin();
for(it;it!=keyword[ss].end();it++){
cout<<*it<<endl;
}
break;
}
case 4:{
printf("%d: ",op);
cout<<ss<<endl;
if(publisher[ss].empty()){
cout<<"Not Found"<<endl;
}
auto it=publisher[ss].begin();
for(it;it!=publisher[ss].end();it++){
cout<<*it<<endl;
}
break;
}
case 5:{
printf("%d: ",op);
cout<<ss<<endl;
if(reyear[ss].empty()){
cout<<"Not Found"<<endl;
}
auto it=reyear[ss].begin();
for(it;it!=reyear[ss].end();it++){
cout<<*it<<endl;
}
break;
}
default:break;
}
}
}
#include
using namespace std;
int a[10];
int ss[25];
int sss[25];
int main(){
string s;
cin>>s;
int l=s.length();
for(int i=1;i<=l;i++){
ss[i]=s[i-1]-'0';
a[ss[i]]++;
}
int f=0;
for(int i=l;i>0;i--){
int t=ss[i]*2;
sss[i]+=t%10;
sss[i-1]=t/10;
//printf("%d %d ",i-1,sss[i-1]);
a[sss[i]]--;
if(a[sss[i]]<0){
f=1;
}
}
if(f){
printf("No\n");
for(int i=0;i<=l;i++){
if(i==0&&sss[i]==0) continue;
printf("%d",sss[i]);
}
return 0;
}
printf("Yes\n");
for(int i=0;i<=l;i++){
if(i==0&&sss[i]==0) continue;
printf("%d",sss[i]);
}
return 0;
}
1024 Palindromic Number
大数加+回文判断
这个大数加的板子很好哇!
#include
using namespace std;
string l_add(string s1,string s2){
int carry = 0;
int partialSum = 0;
string r;
for (int i = s1.size()-1; i >= 0; --i) {// s1和s2实际是一样长的
partialSum = (s1[i]-'0')+(s2[i]-'0')+carry;
carry = partialSum/10;
r += to_string(partialSum%10);
}
// 由于s1和s2是一样长的,就无需判断s1或者s2还有部分需要相加了。
if(carry!=0){
r += to_string(carry);//加上进位
}
reverse(r.begin(),r.end());
return r;
}
int palindromic(string s){
int l=0;
int r=s.length()-1;
while(l<=r){
if(s[l]!=s[r]){
return 0;
}
l++;
r--;
}
return 1;
}
int main(){
string n;
int k;
cin>>n>>k;
int step=0;
while(step<k){
if(palindromic(n)){
break;
}
string s=n;
reverse(n.begin(),n.end());
n=l_add(s,n);
//cout<
step++;
}
cout<<n<<endl<<step<<endl;
return 0;
}
1025 PAT Ranking
题目大意:
给定n组成绩,根据学号输出n组学生组内综合排名、组别和组内排名。
注意排名重复的时候下一个人的排名要后移。
#include
using namespace std;
struct ranker{
string name;
int grade;
int fr,ln,lr;
};
vector<ranker>listt;
vector<ranker>ffr;
int cmp(ranker a,ranker b){
if(a.grade==b.grade){
return a.name<b.name;
}
else return a.grade>b.grade;
}
int main(){
int n,tol=0;
cin>>n;
for(int i=0;i<n;i++){
int k;
scanf("%d",&k);
tol+=k;
for(int j=0;j<k;j++){
ranker t;
cin>>t.name>>t.grade;
listt.push_back(t);
}
sort(listt.begin(),listt.end(),cmp);//计算localrank
for(int j=0;j<k;j++){
ranker t;
t.name=listt[j].name;
t.grade=listt[j].grade;
t.ln=i+1;
int q=j-1,cnt=0;
while(q>=0&&listt[q].grade==t.grade){
cnt++;
q--;
if(q<0) break;
}
t.lr=j+1-cnt;
ffr.push_back(t);
//cout<
}
listt.clear();
}
cout<<tol<<endl;
sort(ffr.begin(),ffr.end(),cmp);
for(int i=0;i<tol;i++){
if(i!=0) cout<<endl;
ranker t;
t.name=ffr[i].name;
t.grade=ffr[i].grade;
t.lr=ffr[i].lr;
t.ln=ffr[i].ln;
int j=i-1,cnt=0;
while(j>=0&&ffr[j].grade==t.grade){
j--;
cnt++;
//if(j<0) break;
}
t.fr=i+1-cnt;
cout<<t.name<<' '<<t.fr<<' '<<t.ln<<' '<<t.lr;
}
}
/*
2
5
1234567890001 95
1234567890005 100
1234567890003 95
1234567890002 77
1234567890004 85
4
1234567890013 65
1234567890011 25
1234567890014 100
1234567890012 85
2
5
1234567890001 100
1234567890005 100
1234567890003 100
1234567890002 100
1234567890004 100
4
1234567890013 65
1234567890011 25
1234567890014 100
1234567890012 85
*/
#include
using namespace std;
int main(){
int a[3];
string c[3];
for(int i=0;i<3;i++){
int temp;
scanf("%d",&temp);
int j=0;
if(temp/13>9){
c[i]=temp/13+'A'-10;
}
else c[i]=temp/13+'0';
if(temp%13>9){
c[i]+=temp%13-10+'A';
}
else{
c[i]+=temp%13+'0';
}
}
cout<<'#';
for(int i=0;i<3;i++){
cout<<c[i];
}
}
//13转16
//int main(){
// string a[3];
// int r=0,g=0,b=0;
// int n=3;
// for(int i=0;i
// cin>>a[i];
// }
// for(int i=0;i
// int l=a[i].length();
// int t=0;
// for(int j=0;j
// if(a[i][j]>='0'&&a[i][j]<='9'){
// t=t*13+a[i][j]-'0';
// }
// else{
// t=t*13+a[i][j]-'A'+10;
// }
// }
// switch(i){
// case 0:{
// r=t;
// break;
// }
// case 1:{
// g=t;
// break;
// }
// case 2:{
// b=t;
// break;
// }
// default:{
// break;
// }
// }
// }
// printf("%d %d %d\n",r,g,b);
// cout<<'#';
// if(r<16) cout<<'0';
// printf("%X",r);
// if(g<16) cout<<'0';
// printf("%X",g);
// if(b<16) cout<<'0';
// printf("%X",b);
//}
#include
using namespace std;
struct st{
string id;
string name;
int grade;
};
int cmp1(st a,st b){
return a.id<b.id;
}
int cmp2(st a,st b){
if(a.name==b.name) return a.id<b.id;
else return a.name<b.name;
}
int cmp3(st a,st b){
if(a.grade==b.grade) return a.id<b.id;
else return a.grade<b.grade;
}
vector<st>student;
int main(){
int n,c;
cin>>n>>c;
for(int i=0;i<n;i++){
st t;
cin>>t.id>>t.name>>t.grade;
student.push_back(t);
}
switch(c){
case 1:{
sort(student.begin(),student.end(),cmp1);
break;
}
case 2:{
sort(student.begin(),student.end(),cmp2);
break;
}
case 3:{
sort(student.begin(),student.end(),cmp3);
break;
}
default:break;
}
for(auto it=student.begin();it!=student.end();it++){
cout<<it->id<<' '<<it->name<<' '<<it->grade<<endl;
}
}
求两个数组合数组的中位数。
#include
using namespace std;
typedef long long ll;
ll a[400010];
int main(){
int n,m;
cin>>n;
for(int i=0;i<n;i++){
cin>>a[i];
}
cin>>m;
for(int i=n;i<n+m;i++){
cin>>a[i];
}
sort(a,a+n+m);
int median=((n+m)*1.0/2+0.5)-1;
cout<<a[median]<<endl;
}
1031 Hello World for U
题目大意:
给一个字符串,让它变成满足条件的U形。
只要算出N2就可以了。
#include
using namespace std;
int main(){
string ss;
cin>>ss;
int n=ss.length();
int c=(n+2)/3;//N2
for(int i=0;i<c-1;i++){
printf("%c",ss[i]);
for(int j=0;j<n-2*c;j++){
printf(" ");
}
printf("%c",ss[n-i-1]);
printf("\n");
}
for(int i=c-1;i<=n-c;i++){
cout<<ss[i];
}
return 0;
}
1035 Password
把字符串中某些字符进行替换,注意输出格式就可以了。
#include
using namespace std;
struct account{
string name;
string pas;
};
vector<account>acc;
int main(){
int n,tol=0;
cin>>n;
for(int i=0;i<n;i++){
string ss,password;
cin>>ss>>password;
int l=password.length(),f=0;
for(int j=0;j<l;j++){
if(password[j]=='1'){
password[j]='@';
f=1;
continue;
}
if(password[j]=='0'){
password[j]='%';
f=1;
continue;
}
if(password[j]=='l'){
password[j]='L';
f=1;
continue;
}
if(password[j]=='O'){
password[j]='o';
f=1;
continue;
}
}
account t;
t.name=ss;
t.pas=password;
if(f){
tol++;
acc.push_back(t);
}
}
if(tol){
printf("%d\n",acc.size());
for(auto x:acc){
cout<<x.name<<' '<<x.pas<<endl;
}
}
else if(n==1) printf("There is %d account and no account is modified",n);
else printf("There are %d accounts and no account is modified",n);
}
比较无聊。
#include
using namespace std;
struct stu{
string name;
string sex;
string id;
};
map<int,stu>male;
map<int,stu>female;
int main(){
int n;
cin>>n;
int m=101,f=-1;
for(int i=0;i<n;i++){
string n,s,d;
int g;
cin>>n>>s>>d>>g;
stu student;
student.name=n;
student.sex=s;
student.id=d;
if(s=="M"){
male[g]=student;
if(m>g) m=g;
}
else{
female[g]=student;
if(f<g) f=g;
}
}
if(f<0) printf("Absent\n");
else{
cout<<female[f].name<<' '<<female[f].id<<endl;
}
if(m>100) printf("Absent\n");
else{
cout<<male[m].name<<' '<<male[m].id<<endl;
}
if(m>100||f<0) printf("NA\n");
else{
printf("%d\n",f-m);
}
}
正数和负数分开排排序,一下就出来啦~
#include
using namespace std;
typedef long long ll;
vector<int>ca;
vector<int>cb;
vector<int>pa;
vector<int>pb;
int cmp(ll a,ll b){
return a>b;
}
int main(){
ll nc,np;
ll ans=0;
cin>>nc;
for(int i=0;i<nc;i++){
ll t;
cin>>t;
if(t<0) cb.push_back(t);
else ca.push_back(t);
}
sort(ca.begin(),ca.end(),cmp);
sort(cb.begin(),cb.end());
cin>>np;
for(int i=0;i<np;i++){
ll t;
cin>>t;
if(t<0) pb.push_back(t);
else pa.push_back(t);
}
sort(pa.begin(),pa.end(),cmp);
sort(pb.begin(),pb.end());
ll p=0;
while(p!=ca.size()&&p!=pa.size()){
ans+=ca[p]*pa[p];
p++;
}
p=0;
while(p!=cb.size()&&p!=pb.size()){
ans+=cb[p]*pb[p];
p++;
}
cout<<ans<<endl;
}
练练STL还是挺不错的哈~
#include
using namespace std;
map<string,set<int>>qq;
int main(){
int n,k;
cin>>n>>k;
for(int t=0;t<k;t++){
int ni,nk;
cin>>ni>>nk;
for(int i=0;i<nk;i++){
string name;
cin>>name;
qq[name].insert(ni);
}
}
int num=n;
for(int i=0;i<num;i++){
string name;
int f=0;
cin>>name;
cout<<name<<' ';
int num_q=qq[name].size();
cout<<num_q;
/*if(!num_q){
cout<<' ';
}
else{
continue;
}*/
for(auto x:qq[name]){
cout<<' '<<x;
f++;
}
cout<<endl;
}
return 0;
}
题意:寻找最长回文子串。
马拉车的经典问题?
但是我就不拉!
思路就是挨个遍历,遍历的时候由中心点向两边扩散。
#include
using namespace std;
string s;
int len;
int cal(int l, int r) {
int ret = 0;
while(l >=0 && r < len && s[l--] == s[r++]) {
ret += 2;
}
return ret;
}
int main() {
getline(cin, s);
len = s.length();
int ans = 0;
for(int i = 0; i < len; ++i) {
ans = max(ans, 1 + cal(i - 1, i + 1));
if(i > 0)
ans = max(ans,cal(i - 1, i));
}
cout << ans <<endl;
return 0;
}
1041 Be Unique
题目大意:给n个数字,输出这个n个数字里面第一个不重复的数字。如果不存在输出none。
思路:输入的时候遍历nn,如果没有,则放入,如果有,在nn中清楚放入set(以防下次出现),最终nn中只会剩下没有重复过的。
#include
using namespace std;
vector<int>nn;
set<int>used;
int main(){
int n;
cin>>n;
for(int i=0;i<n;i++){
int t;
scanf("%d",&t);
auto it=find(nn.begin(),nn.end(),t);
if(it!=nn.end()){//如果有重复清除并更新set
nn.erase(it);
used.insert(t);
}
else if(used.count(t)){//set中存在
continue;
}
else nn.push_back(t);//如果不存在则加入
}
if(nn.empty()){
printf("None");
}
else printf("%d",nn[0]);
}
1042 Shuffling Machine
大意:有一副牌,54张按顺序放好。现在要求把第i张牌放到第j的位置上去。给定j的序列和重排次数,求重排结束后的牌组序列。
#include
using namespace std;
map<int,string>card;
map<int,string>tmp;
int main(){
int n;
cin>>n;
for(int i=1;i<=13;i++){
card[i]="S"+to_string(i);
}
for(int i=14;i<=26;i++){
card[i]="H"+to_string(i-13);
}
for(int i=27;i<=39;i++){
card[i]="C"+to_string(i-26);
}
for(int i=40;i<=52;i++){
card[i]="D"+to_string(i-39);
}
card[53]="J1";
card[54]="J2";//初始化牌组
int t[55];
for(int i=1;i<=54;i++){
cin>>t[i];
}
for(int k=0;k<n;k++){
for(int i=1;i<=54;i++){
tmp[t[i]]=card[i];
//cout<
}//按照上次的排序更新这次的牌组
card=tmp;
}
for(int i=1;i<=54;i++){
if(i>1) cout<<' ';
cout<<card[i];
}
cout<<endl;
}
这是一道二叉搜索树的题。
题意大概是:给一组数据,判断这组数据是否是二叉搜索树的先序遍历,如果不是,是否是二叉搜索树的镜像遍历,如果符合上述两种输"YES",否则输出"NO"。
学的是柳神的代码…
顺带自己学了一下二叉搜索树。
简单再赘述一下柳神的思想:对这组数据分别从两端进行遍历,看root两边是否符合二叉搜索树的先序遍历顺序,如果符合,就把这个root放进post向量里面。如果不符合,就return,观察post向量长度是否与原来给的数据长度一致,不一致的话观察镜像顺序。如果都不是,则输出"NO"。
#include
using namespace std;
vector<int>pre,post;//pre是原数组,post是判断数组
bool is;//判断是否是镜像
void getpost(int r,int t){
if(r>t) return;
int i=r+1,j=t;
//cout<
if(!is){
while(i<=t && pre[r]>pre[i]) i++;//如果指向的数字小于根,说明符合向后走
while(j>r && pre[r]<=pre[j]) j--;//如果指向的数字大于等于根,说明符合向前走
}
else{
while(i<=t && pre[r]<=pre[i]) i++;
while(j>r && pre[r]>pre[j]) j--;
//镜像
}
//cout<
if(i-j != 1) return ;
getpost(r+1,j);//左子树
getpost(i,t);//右子树
post.push_back(pre[r]);
}
int main(){
int n;
cin>>n;
pre.resize(n);
for(int i=0;i<n;i++){
scanf("%d",&pre[i]);
}
getpost(0,n-1);
if(post.size()!=n){
is=true;
post.clear();//如果不是二叉搜索树,接下来判断镜像
getpost(0,n-1);
}
if(post.size() == n){
printf("YES\n%d",post[0]);
for(int i=1;i<n;i++){
printf(" %d",post[i]);
}
}
else{
printf("NO\n");
}
return 0;
}
很基础的题。跟图啥的没关系。
暴力的时候T了一发。
第一次真的是太暴力了…每次都重新计算了距离。
然后就换了用前缀和来写。
反正是个环形的,规律也很好找。
#include
using namespace std;
int n;
typedef long long ll;
int d[100010];
ll dist[100010];
void dis(int x,int y){
if(x>y) swap(x,y);
if(x==y){
printf("0\n");
return ;
}
ll dist1=dist[y]-dist[x];//逆时针数
ll dist2=dist[x]-dist[1]+dist[n]-dist[y]+d[n];//顺时针数
printf("%lld\n",dist1<dist2?dist1:dist2);
}
int main(){
cin>>n;
dist[1]=0;
for(int i=1;i<=n;i++){
cin>>d[i];
dist[i+1]=dist[i]+d[i];
}
dist[0]=d[n];//记录的是Dn到D1的距离
int m;
cin>>m;
for(int i=0;i<m;i++){
int x,y;
cin>>x>>y;
dis(x,y);
}
}
错误写法:
卡cin、cout,怎么改都不对…
都是最后一个测试点超时。
#include
using namespace std;
//unordered_map>st;
//unordered_map>st;
vector<string> st[40050];
int cmp(string a,string b){
return a<b;
}
int main(){
ios::sync_with_stdio(false);
int n,k;
//scanf("%d%d",&n,&k);
cin>>n>>k;
for(int i=0;i<n;i++){
string name;
cin>>name;
int kk;
cin>>kk;
while(kk--){
int t;
cin>>t;
//st[t].insert(name);
st[t].push_back(name);
}
}
for(int i=1;i<=k;i++){
//printf("%d %d\n",i,st[i].size());
int tmp=st[i].size();
cout<<i<<' '<<tmp<<endl;
/*for(auto x:st[i]){
cout<
sort(st[i].begin(),st[i].end(),cmp);
for(auto x:st[i]){
cout<<x<<endl;
}
}
return 0;
}
正确写法,改用scanf和printf。
#include
using namespace std;
struct st{
char name[5];
};
vector<vector<st>>stt;
int cmp(st a,st b){
if(strcmp(a.name,b.name)>0) return 0;
else return 1;
}
int main(){
int n,k;
cin>>n>>k;
stt.resize(k+1);
for(int i=0;i<n;i++){
st stu;
scanf("%s",&stu.name);
int kk;
cin>>kk;
for(int j=0;j<kk;j++){
int t;
cin>>t;
stt[t].push_back(stu);
}
}
for(int i=1;i<=k;i++){
int tt=stt[i].size();
printf("%d %d\n",i,tt);
sort(stt[i].begin(),stt[i].end(),cmp);
for(int j=0;j<tt;j++){
printf("%s\n",&stt[i][j]);
}
}
return 0;
}
找是否有两个数相加能取到某个值。
数组开大,别的没啥。
#include
using namespace std;
int M[10100];
int d[100100];
int main(){
int n,m;
int v1=1000,v2=-1;
cin>>n>>m;
for(int i=0;i<n;i++){
cin>>d[i];
M[d[i]]++;
}
for(int i=0;i<n;i++){
int tv1=1010,tv2;
int t=m-d[i];
M[d[i]]--;
if(M[t]){
M[t]--;
tv1=t<d[i]?t:d[i];
tv2=t>d[i]?t:d[i];
if(tv1<v1){
v1=tv1;
v2=tv2;
}
}
else{
M[d[i]]++;
}
}
if(v2<0) printf("No Solution\n");
else cout<<v1<<' '<<v2<<endl;
}
思路:用map记录S2,搜索S1。
#include
using namespace std;
map<char,int>ss;
int main(){
string s1,s2;
getline(cin,s1);
getline(cin,s2);
//memset(ss,0,sizeof(ss));
int l1=s1.length(),l2=s2.length();
for(int i=0;i<l2;i++){
ss[s2[i]]=1;
}
for(int i=0;i<l1;i++){
if(ss[s1[i]]) continue;
else printf("%c",s1[i]);
}
cout<<endl;
return 0;
}
细节题。
#include
using namespace std;
struct node{
string adr;
int key;
string next;
};
vector<node>tt;
//node tmp[100010];
unordered_map<string,node>tmp;
int cmp(node a,node b){
return a.key<b.key;
}
int main(){
ios::sync_with_stdio(false);//不加第四个点会超时
int n;
string s;
cin>>n>>s;
for(int i=0;i<n;i++){
node temp;
cin>>temp.adr>>temp.key>>temp.next;
tmp[temp.adr]=temp;
}
node temp=tmp[s];
if(tmp[s].key==0 && temp.next==""){
printf("0 -1\n");
return 0;
}//特判这个,给出的s不在所有给出的节点中,卡了好久...
while(temp.next!="-1"){
tt.push_back(temp);
temp=tmp[temp.next];
}
if(temp.next=="-1") tt.push_back(temp);
sort(tt.begin(),tt.end(),cmp);
cout<<tt.size()<<" "<<tt[0].adr<<endl;
for(int i=0;i<tt.size();i++){
if(i==tt.size()-1){
cout<<tt[i].adr<<' '<<tt[i].key<<' '<<-1<<endl;
}
else cout<<tt[i].adr<<' '<<tt[i].key<<' '<<tt[i+1].adr<<endl;
}
return 0;
}
题意:
这个题也太难理解了(也可能我英语水平有限…
第一行给np,ng代表np只老鼠和把ng只老鼠分成一组。
input:
11 3
25 18 0 46 37 3 19 22 57 56 10 //这一行是说第i只老鼠的重量是w
6 0 8 7 10 5 9 1 4 2 3 //这一行给出的其实是老鼠的序号,按照给出的序号顺序进行分组。
output:
5 5 5 2 5 5 5 3 1 3 5 //最后按照序号从小到大输出
#include
using namespace std;
struct mice{
int weight;
int index;
int index0;
int rank;
};
vector<mice>res;
vector<int>w;
int cmp1(mice a,mice b){
return a.index0<b.index0;//按照给定序号从小到大排序
}
//题意好难理解
int main(){
int np,ng,temp;
scanf("%d%d",&np,&ng);
w.resize(np);
res.resize(np);
for(int i=0;i<np;i++){
scanf("%d",&w[i]);
}
for(int i=0;i<np;i++){
scanf("%d",&temp);
res[i].weight=w[temp];
res[i].index=i;//这个是分组index
res[i].index0=temp;//temp是给定的序号的,对应weight
}//res是按照分组顺序排列的
queue<mice>q;
for(int i=0;i<np;i++){
q.push(res[i]);
}
while(!q.empty()){
int size=q.size();
if(size==1){//当队列中仅剩一只老鼠就结束
mice last=q.front();
res[last.index].rank=1;
break;
}
int group=size/ng;//巧妙的分组计算
if(size%ng!=0){
group+=1;
}
mice maxmice;
int maxn=-1,cnt=0;
for(int i=0;i<size;i++){
mice last=q.front();// 从头遍历,不能进入下一组直接pop
res[last.index].rank=group+1;
q.pop();
cnt++;
if(last.weight>maxn){
maxn=last.weight;
maxmice=last;
}
if(cnt==ng||i==size-1){//满一组的话就把最大的存进下一组
cnt=0;
maxn=-1;
q.push(maxmice);
}
}
}
sort(res.begin(),res.end(),cmp1);//根据序号排序
for(int i=0;i<np;i++){
if(i!=0) cout<<' ';
printf("%d",res[i].rank);
}
return 0;
}
#include
using namespace std;
typedef long long ll;
int main(){
ll a1,b1,c1;
int a2,b2,a3,b3,c2,c3;
scanf("%lld.%d.%d",&a1,&a2,&a3);
scanf("%lld.%d.%d",&b1,&b2,&b3);
c3=a3+b3;
c2=a2+b2;
c1=a1+b1;
if(c3>28){
c2+=c3/29;
c3=c3%29;
}
if(c2>16){
c1+=c2/17;
c2%=17;
}
printf("%lld.%d.%d\n",c1,c2,c3);
}
分解质因子模板:
#include
using namespace std;
typedef long long ll;
map<int,int>ans;
int main(){
ll n;
scanf("%lld",&n);
if(n==1){
printf("1=1\n");
return 0;
}
ll tmp=n;
for(int i=2;i<=n||n>1;i++){//分解质因子模板
while(n%i==0){
++ans[i];
n/=i;
}
//if(n!=1) ans[n]=1;
}//到这里结束
printf("%ld=",tmp);
int cnt=0;
for(int i=2;i<=tmp;i++){
if(ans[i]>1) {
if(cnt){
printf("*");
}
cnt++;
printf("%d^%d",i,ans[i]);
tmp/=i;
}
else if(ans[i]==1){
if(cnt){
printf("*");
}
cnt++;
//if(i!=2) printf("*");
printf("%d",i);
tmp/=i;
}
//printf(" %ld\n",tmp);
}
cout<<endl;
return 0;
}
哭哭…。
卡题了…
刚开始硬分类讨论…忽略了 4 0.00000 000000.00000这种…
然后分别处理A B串,一样的操作写了100+行,本来是想偷个懒,结果debug极其难搞。
深刻认识到模块化、面向对象的重要性!!!
既然对A、B串的处理一样,那就要写一个函数解决它!
#include
using namespace std;
int f(const string&a,string&ppa,int n){
//cout<
int pta=a.size(),sa=-1;
for(int i=0;i<a.size();i++){
if(a[i]=='.'){
pta=i;
}
else if(sa!=-1&&ppa.size()<n){
ppa+=a[i];
}
else if(sa==-1&&a[i]!='0'){
sa=i;
ppa+=a[i];
}
}
while(ppa.size()<n){
ppa+="0";
}
if(sa==-1) return 0;
pta-=sa;
return pta<0?pta+1:pta;
}
int main(){
int n;
scanf("%d",&n);
string a,b;
cin>>a>>b;
int la=0,lb=0;
string ppa="",ppb="";
la=f(a,ppa,n);
lb=f(b,ppb,n);
if(la==lb){
if(ppa==ppb){
cout<<"YES 0."<<ppa<<"*10^"<<la<<endl;
return 0;
}
}
cout<<"NO 0."<<ppa<<"*10^"<<la<<" 0."<<ppb<<"*10^"<<lb<<endl;
}
/*
4 0.000001 1
3 1.2 0.00001
1 0.000001 3000
*/
#include
using namespace std;
string day[8]={"MON","TUE","WED","THU","FRI","SAT","SUN"};
int main(){
string s1,s2,s3,s4;
cin>>s1>>s2>>s3>>s4;
int l1=s1.length(),l2=s2.length(),l3=s3.length(),l4=s4.length();
int minn=min(l1,l2);
int a=-1,b=-1,c=-1;
int i=0;
for(i=0;i<minn;i++){
if(s1[i]==s2[i]&&(s1[i]>='A'&&s1[i]<='G')){
if(a<0){
a=s1[i]-'A';
break;
}
}
}
i++;
for(;i<minn;i++){
if(s1[i]==s2[i]&&((s1[i]>='A'&&s1[i]<='N')||(isdigit(s1[i])))){
if(isdigit(s1[i])){
b=s1[i]-'0';
break;
}
else{
b=s1[i]-'A'+10;
break;
}
}
}
minn=min(l3,l4);
for(int i=0;i<minn;i++){//((s3[i]>='a'&&s3[i]<='z')||(s3[i]>='A'&&s3[i]<='Z'))
if(s3[i]==s4[i]&&isalpha(s3[i])){
c=i;
break;
}
}
cout<<day[a]<<' ';
printf("%02d:%02d\n",b,c);
}
没有意思。
#include
using namespace std;
struct person{
string id;
int vg,tg;
int tol;
};
person p[100010];
vector<person>sages;
vector<person>noble;
vector<person>fool;
vector<person>normal;
int cmp1(person a,person b){
if(a.tol!=b.tol) return a.tol>b.tol;
else if(a.vg!=b.vg) return a.vg>b.vg;
else return a.id<b.id;
}
int main(){
ios::sync_with_stdio(false);
int n,l,h,des=0;
cin>>n>>l>>h;
//scanf("%d%d%d",&n,&l,&h);
for(int i=0;i<n;i++){
cin>>p[i].id>>p[i].vg>>p[i].tg;
p[i].tol=p[i].vg+p[i].tg;
if(p[i].vg<l || p[i].tg<l){
des++;
continue;
}
else if(p[i].vg>=h && p[i].tg>=h){
sages.push_back(p[i]);
}
else if(p[i].vg>=h && p[i].tg<h){
noble.push_back(p[i]);
}
else if(p[i].vg<h && p[i].tg<h && p[i].vg>=p[i].tg){
fool.push_back(p[i]);
}
else normal.push_back(p[i]);
}
sort(sages.begin(),sages.end(),cmp1);
sort(noble.begin(),noble.end(),cmp1);
sort(fool.begin(),fool.end(),cmp1);
sort(normal.begin(),normal.end(),cmp1);
cout<<n-des<<endl;
for(auto x:sages){
cout<<x.id<<' '<<x.vg<<' '<<x.tg<<endl;
}
for(auto x:noble){
cout<<x.id<<' '<<x.vg<<' '<<x.tg<<endl;
}
for(auto x:fool){
cout<<x.id<<' '<<x.vg<<' '<<x.tg<<endl;
}
for(auto x:normal){
cout<<x.id<<' '<<x.vg<<' '<<x.tg<<endl;
}
return 0;
}
学个STL小技术:
交并集之类。
set_intersection(取集合交集)、set_union(取集合并集)、set_difference(取集合差集)、set_symmetric_difference(取集合对称差集)等函数
格式:
function(set1.begin( ), set1.end( ), set2.begin( ), set2.end( ), inserter(set/vector x, x.begin( ) ) )
#include
using namespace std;
typedef long long ll;
set<int>ss[55];
vector<int>uni;
vector<int>inter;
int main(){
int n;
scanf("%d",&n);
for(int i=0;i<n;i++){
int m;
scanf("%d",&m);
ll temp;
for(int j=0;j<m;j++){
scanf("%d",&temp);
ss[i+1].insert(temp);
}
}
/*for(int i=0;i
int k;
scanf("%d",&k);
for(int i=0;i<k;i++){
int a,b;
scanf("%d%d",&a,&b);
set_union(ss[a].begin(),ss[a].end(),ss[b].begin(),ss[b].end(),inserter(uni,uni.begin()));
set_intersection(ss[a].begin(),ss[a].end(),ss[b].begin(),ss[b].end(),inserter(inter,inter.begin()));
//printf("%d,%d ",uni.size(),inter.size());
double sim;
sim=1.0*inter.size()/uni.size()*100;
printf("%.1f%%\n",sim);
uni.clear();
inter.clear();
}
}
注意观察题意!
A 、 B 、 C ∈ [ − 2 63 , 2 63 ] A、B、C∈[-2^{63}, 2^{63}] A、B、C∈[−263,263]
在 l o n g l o n g 类 型 中 , 最 大 范 围 是 [ − 2 63 , 2 63 − 1 ] 在longlong类型中,最大范围是[-2^{63}, 2^{63}-1] 在longlong类型中,最大范围是[−263,263−1]
数据范围比较特殊,所以存在溢出的情况,特判溢出就好了。
#include
using namespace std;
typedef long long ll;
int main(){
int n;
scanf("%d",&n);
ll a,b,c;
ll sum;
for(int i=0;i<n;i++){
scanf("%lld%lld%lld",&a,&b,&c);
sum=a+b;
if(a>0 && b>0 && sum<0){
printf("Case #%d: true\n",i+1);
}
else if(a<0 && b<0 &&sum>=0){
printf("Case #%d: false\n",i+1);
}
else if(sum>c) printf("Case #%d: true\n",i+1);
else printf("Case #%d: false\n",i+1);
}
return 0;
}
参考博文:
https://blog.csdn.net/qq_25343557/article/details/89110319
讲平衡二叉树,很详细!
代码是参考别人参考的柳神代码…
#include
using namespace std;
struct node{
int value;
//int height;
node *left;
node *right;
};
//左旋:将节点的右孩子变为根,右孩子的左孩子变为原根的右孩子
node *RR(node *root){//左旋 右子树上插右孩子
node *t=root->right;// 将节点的右孩子变为根
root->right=t->left;//右孩子的左孩子变为原根的右孩子
t->left=root;//新根的左孩子是原根
return t;
}
node *LL(node *root){//右旋 左子树插左孩子
node *t=root->left;
root->left=t->right;
t->right=root;
return t;
}
//左子树左旋后整体右旋
node *LR(node *root){//先左后右 左子树插右孩子
root->left=RR(root->left);
return LL(root);
}
//右子树右旋后整体左旋
node *RL(node *root){
root->right=LL(root->right);
return RR(root);
}
int getHeight(node *root){
if(root == NULL) return 0;
return max(getHeight(root->left),getHeight(root->right))+1;
}
//先插入,判断是否平衡,不平衡判断插在哪里,旋转
node *insert(node *root,int val){
if(root==NULL){
root=new node();
root->value=val;
root->left=root->right=NULL;
}
else if(val < root->value){//小于本节点放左边
root->left = insert(root->left,val);
if(getHeight(root->left)-getHeight(root->right)==2){
root = val < root->left->value ? LL(root):LR(root);
} //左右子树不平衡 val小于 root->left->value 继续左插,右旋
//大于左子树上插右子树 先左后右
}
else{
root->right=insert(root->right,val);
if(getHeight(root->left)-getHeight(root->right)==-2){
root = val > root->right->value ? RR(root):RL(root);
}
}
return root;
}
int main(){
int n,val;
scanf("%d",&n);
node *root=NULL;
for(int i=0;i<n;i++){
scanf("%d",&val);
root=insert(root,val);
}
printf("%d",root->value);
return 0;
}
有意思嗷。
#include
using namespace std;
int a[100010];//记录排好序的
int main(){
int n,ans=0;
scanf("%d",&n);
for(int i=0;i<n;i++){
scanf("%d",&a[i]);
}
for(int i=1;i<n;i++){
if(i!=a[i]){
while(a[0]!=0){
swap(a[0],a[a[0]]);//a[0]处数字归位置
ans++;
}
if(i!=a[i]){//与哨兵交换
swap(a[0],a[i]);
ans++;
}
}
}
printf("%d\n",ans);
return 0;
}
注意D的范围!
贪心,单价最高的先卖。
#include
using namespace std;
struct cake{
double tol;
double p;
};
cake m[1010];
int cmp(cake a,cake b){
return a.p>b.p;
}
int main(){
int n;
double tol=0.0;
//double ans=0.0;
double pro=0.0;
scanf("%d%lf",&n,&tol);
for(int i=0;i<n;i++){
scanf("%lf",&m[i].tol);
}
for(int i=0;i<n;i++){
double t;
scanf("%lf",&t);
m[i].p=t*1.0/m[i].tol;
}
sort(m,m+n,cmp);
for(int i=0;i<n;i++){
if(tol-m[i].tol>=0){
pro+=(m[i].p*m[i].tol);
tol-=m[i].tol;
//pro+=(tol-ans)*m[i].p;
//break;
}
else{
pro+=(tol*m[i].p);
break;
}
}
printf("%.2f\n",pro);
}
#include
using namespace std;
map<string,int>num;
int main(){
//printf("%d\n",'a'-'A');
string ss;
getline(cin,ss);
string tmp="";
for(int i=0;i<ss.length();i++){
if(isalnum(ss[i])){
tmp+=tolower(ss[i]);
}
else if(tmp.length()>0){
num[tmp]++;
tmp="";
}
}
//记最后一个词!
if(!tmp.empty()){
num[tmp]++;
}
int maxx=-1;
for(auto x:num){
if(x.second>maxx){
maxx=x.second;
tmp=x.first;
}
else if(x.second==maxx){
if(tmp<x.first){
maxx=x.second;
tmp=x.first;
}
}
//cout<
}
cout<<tmp<<' '<<maxx<<endl;
}
#include
using namespace std;
int main(){
string ss;
cin>>ss;
char ch1,ch2;
ch1=ss[0];
string head="";
string tail="";
int sc=0;
int f=0;
int i=0;
for(i=1;i<ss.length();i++){
if(ss[i]=='.'){
f=1;
continue;
}
if(!f){
head+=ss[i];
}
else{
if(ss[i]=='E'){
break;
}
tail+=ss[i];
}
}
i++;
ch2=ss[i++];
for(i;i<ss.length();i++){
sc=sc*10+(ss[i]-'0');
}
//printf("%d\n",sc);
string ans="";
if(sc==0){
ans=head;
if(tail!=""){
ans+=("."+tail);
}
cout<<ans<<endl;
return 0;
}
if(ch2=='+'){
if(ch1=='-') ans+=ch1;
if(tail.length()>sc){
string t;
t=tail.substr(0,sc);
tail=tail.substr(sc,tail.length()-sc);
tail=t+"."+tail;
ans+=(head+tail);
}
else{
ans+=(head+tail);
int num=sc-tail.length();
for(int j=0;j<num;j++){
ans+='0';
}
}
}
else{
if(ch1=='-') ans+=ch1;
//if(sc>0) ans+="0.";
if(head.length()>sc){
string t;
t=head.substr(0,sc);
head=head.substr(sc,tail.length()-sc);
head=t+"."+head;
ans+=(head+tail);
}
else{
ans+="0.";
for(int j=0;j<sc-head.length();j++){
ans+='0';
}
ans+=(head+tail);
}
}
cout<<ans<<endl;
}
看错题了。
每k位反转一次,不是反转前k位。
找出link list 压入vector就是链表的顺序,反转后按序输出就可以。
#include
using namespace std;
struct node{
int add;
int d;
int next;
};
node l1[1000010];
vector<node>ll;
int main(){
int add,n,k;
scanf("%d%d%d",&add,&n,&k);
for(int i=0;i<n;i++){
int tadd,tt,tnext;
scanf("%d%d%d",&tadd,&tt,&tnext);
l1[tadd].add=tadd;
l1[tadd].d=tt;
l1[tadd].next=tnext;
}
int p=add;
while(p!=-1){
ll.push_back(l1[p]);
p=l1[p].next;
}
int num=ll.size()/k;
for(int i=0;i<num;i++){
reverse(ll.begin()+i*k,ll.begin()+i*k+k);
}
for(int i=0;i<ll.size()-1;i++){
printf("%05d %d %05d\n",ll[i].add,ll[i].d,ll[i+1].add);
}
printf("%05d %d -1\n",ll[ll.size()-1].add,ll[ll.size()-1].d);
return 0;
}```