1.13-1.16做过的题
题目:6-2 多项式求值(15分)
简单
double f(int n,double a[],double x)
{
double ans=0;
double tx=1;
for(int i=0;i<=n;i++)
{
ans=ans+a[i]*tx;
tx=tx*x;
}
return ans;
}
题目:L1-087 机工士姆斯塔迪奥(20分)
要考虑重合的格子
#include<stdio.h>
int main()
{
int n = 0;
int m = 0;
int q = 0;
scanf("%d %d %d",&n,&m,&q);
int i = 0;
int t = 0;
int c = 0;
int countrow = 0;
int countcol = 0;
int row[100001]={0};
int col[100001]={0};
for(i=0;i<q;i++)
{
scanf("%d %d",&t,&c);
if(t==0)
{
if(row[c]!=1)
{
countrow++;
row[c]=1;
}
}
else
{
if(col[c]!=1)
{
countcol++;
col[c]=1;
}
}
}
printf("%d",m*n-countrow*m-countcol*n+(countrow*countcol));
return 0;
}
题目:7-35 城市间紧急救援(25分)
迪杰斯特拉最短路
#include <stdio.h>
#include <stdlib.h>
#define INF 0xFFFFFF
int n,m,s,d;
int dis[500];//最短路数组
bool check[500]={false};//是否被选择过的结点数组
int countn[500]={0};//最短路径数量
int weith[500];//每个结点的救援队数量
int w[500];//从出发点到支援点的救援队总数
int graph[500][500];//邻接矩阵
int v[500];//结点的最短后继
void Dijkstra(){
int i,j;
w[s]=weith[s];
dis[s]=0;
countn[s]=1;
for(i=0;i<n;i++){
int minx,minn=INF;
for(j=0;j<n;j++){
if(dis[j]<minn&&check[j]!=true){//找出当前的最短点
minx=j;
minn=dis[j];
}
}
check[minx]=true;
for(j=0;j<n;j++){
if(graph[minx][j]>0){
if(minn+graph[minx][j]<dis[j]){
dis[j]=minn+graph[minx][j];
w[j]=weith[j]+w[minx];
v[j]=minx;//当前点的最短路径的前一个结点
countn[j]=countn[minx];
}
else if(minn+graph[minx][j]==dis[j]){
countn[j]=countn[minx]+countn[j];
if(w[minx]+weith[j]>w[j]){
v[j]=minx;
w[j]=w[minx]+weith[j];
}
}
}
}
}
//for(i=0;i<n;i++)
// printf("%d ",countn[i]);
}
int main(){
scanf("%d%d%d%d",&n,&m,&s,&d);
int i,j;
for(i=0;i<n;i++)
scanf("%d",&weith[i]);
for(i=0;i<n;i++){
for(j=0;j<n;j++){
dis[j]=INF;
}
}
for(i=0;i<m;i++){
int a,b,c;
scanf("%d%d%d",&a,&b,&c);
graph[a][b]=c;
graph[b][a]=c;
}
Dijkstra();
int t[500];
i=0;
for(j=d;j>=0;j=v[j]){
t[i++]=j;
if(j==0)
break;
}
printf("%d %d\n",countn[d],w[d]);
for(i--;i>=0;i--){
printf("%d",t[i]);
if(i!=0)
printf(" ");
}
return 0;
}
#include <bits/stdc++.h>
using namespace std;
int f(int p,int q){
if (q==0) return p;
int r = p%q;
return f(q,r);
}
int main()
{
int n;
scanf("%d",&n);
int i,sum=0,pr=1,a,b,t;
for(i=0;i<n;i++)
{
scanf("%d/%d",&a,&b);
if(a==0 || b==0)
continue;
sum=sum*b+a*pr;
pr*=b;
if(i==n-1)
pr*=n;
t=f(sum,pr);
sum/=t;
pr/=t;
}
if(sum==0){
cout<<0<<endl;
}else if(pr!=1){
printf("%d/%d",sum,pr);
}else{
printf("%d",sum);
}
}
题目:L2-023 图着色问题(25分)
邻接矩阵
#include <bits/stdc++.h>
using namespace std;
int d[510][510];
int c[510];
int main()
{
int V,E,K;
cin>>V>>E>>K;
for(int i=1;i<=E;i++)
{
int a,b;
cin>>a>>b;
d[a][b]=d[b][a]=1;
}
int M;
cin>>M;
while(M--)
{
bool ans=true;
set<int> s;
for(int i=1;i<=V;i++)
{
scanf("%d",&c[i]);
s.insert(c[i]);
}
for(int i=1;i<=V;i++)
{
for(int j=1;j<=V;j++)
if(d[i][j]&&c[i]==c[j])
ans=false;
}
if(s.size()!=K)
cout<<"No"<<endl;
else if(ans)
cout<<"Yes"<<endl;
else
cout<<"No"<<endl;
}
}
#include<bits/stdc++.h>
using namespace std;
int n,m,k;
vector<int>a,b;//a存女生,b存男生(用于输入的时候计算亲密度)
set<int>A,B;//A存女生,B存男生(用于最后输出的时候遍历找出最大亲密度)用set可以忽略那些重复出现的人
double g[1005][1005], maxn[1005];//g[][]存放每一对异性的亲密度,maxn存放一个人对另外异性的最大亲密度
int main()
{
cin>>n>>m;
string s;
while(m--)
{
cin>>k;
a.clear();
b.clear();
for(int i=0; i<k; i++)
{
cin>>s;
if(s[0] == '-')//女生情况
{
a.push_back(abs(stoi(s)));
A.insert(abs(stoi(s)));
}
else//男生
{
b.push_back(stoi(s));
B.insert(abs(stoi(s)));
}
}
for(int i=0; i<a.size(); i++)//计算每一张照片中所有异性的亲密的
{
for(int j=0; j<b.size(); j++)
{
g[a[i]][b[j]] += 1.0/k;
g[b[j]][a[i]] += 1.0/k;
if(maxn[a[i]] < g[a[i]][b[j]])//找出每个人最大的亲密的
maxn[a[i]] = g[a[i]][b[j]];
if(maxn[b[j]] < g[b[j]][a[i]])
maxn[b[j]] = g[b[j]][a[i]];
}
}
}
string s1, s2;
cin>>s1>>s2;//情侣的编号
int aa = abs(stoi(s1));
int bb = abs(stoi(s2));
if(maxn[aa] == g[aa][bb] && maxn[bb] == g[bb][aa])//如果情侣之间的亲密度都是最大的
{
cout<<s1<<" "<<s2;
return 0;
}
if(s1[0] == '-')//如果先输入女生
{
for(auto p:B)
{
if(maxn[aa] == g[aa][p])
cout<<s1<<" "<<p<<endl;
}
}
else
{
for( auto p:A)
{
if(maxn[aa] == g[aa][p])
cout<<s1<<' '<<'-'<<p<<endl;
}
}
if(s2[0]=='-')//如果后输入女生
{
for(auto p:B)
if(maxn[bb]==g[bb][p])
cout<<s2<<' '<<p<<endl;
}
else
{
for(auto p:A)
if(maxn[bb]==g[bb][p])
cout<<s2<<' '<<'-'<<p<<endl;
}
return 0;
}
#include<stdio.h>
int main() {
int a[1001] = {0},b[1001] = {0};
int k1,k2;
scanf("%d",&k1);
for(int i = 0 ; i < k1;i ++) {
int xishu,zhishu;
scanf("%d %d",&xishu,&zhishu);
a[zhishu] = xishu;
}
scanf("%d",&k2);
for(int i = 0; i < k2; i++) {
int xishu,zhishu;
scanf("%d %d",&xishu,&zhishu);
b[zhishu] = xishu;
}
int cnt = 0;
int c[10003] = {0};
for(int i = 0 ; i <=1000; i++) {
for(int j = 0; j <= 1000 ; j ++) {
int xishu1 = a[i] * b[j];
int zhishu1 = i + j;
if(xishu1 != 0) {
c[zhishu1] += xishu1;
cnt++;
}
}
}
int flag = 1;
if(cnt == 0) {
printf("0 0\n");
} else {
for(int i = 10000; i >= 0 ; i-- ) {
if(c[i] != 0 ){
if(flag == 0) {
printf(" ");
}
printf("%d %d",c[i],i);
flag = 0;
}
}
printf("\n");
}
flag = 1;
cnt = 0;
for(int i = 0; i <=1000; i++) {
a[i] += b[i];
if(a[i] != 0) {
cnt++;
}
}
if(cnt == 0) {
printf("0 0");
} else {
for(int i = 1000; i >= 0 ; i-- ) {
if(a[i] != 0 ){
if(flag == 0) {
printf(" ");
}
printf("%d %d",a[i],i);
flag = 0;
}
}
}
return 0;
}
题目:7-52 两个有序链表序列的交集
最后一个测试点有坑
求交集函数:set_intersection()
#include <bits/stdc++.h>
using namespace std;
int main()
{
vector<int> v1;
vector<int> v2;
vector<int> ans;
int n;
while(cin>>n,n!=-1)
{
v1.push_back(n);
}
while(cin>>n,n!=-1)
{
v2.push_back(n);
}
set_intersection(v1.begin(),v1.end(),v2.begin(),v2.end(),back_inserter(ans));
int f=0;
if(ans.size()==0)
{
cout<<"NULL";
return 0;
}
for(auto i:ans)
{
if(f==0)
cout<<i,f=1;
else
cout<<' '<<i;
}
}
题目:7-3 树的同构(25分)
树是否同构的判别就是父节点是否相同
#include <bits/stdc++.h>
using namespace std;
int main(void)
{
short N1,i;
short father1[N1];
char data1[N1];
short node1[26],node2[26];
short appear1[26],appear2[26]; //出现的字符
short flag=1; //表示是否为同构树
cin>>N1;
for(i=0;i<26;i++)
appear1[i]=appear2[i]=0; //都没有出现
for(i=0;i<N1;i++)
father1[i]=i; //先初始化为自己
for(i=0;i<N1;i++){
char m0,m1,m2;
cin>>m0>>m1>>m2;
data1[i]=m0; //第i号节点的字符
node1[m0-'A']=i; //某个字符属于的节点编号
appear1[m0-'A']=1;
if('-'!=m1)
father1[m1-'0']=i;
if('-'!=m2)
father1[m2-'0']=i;
} //记录父节点以及每个节点的字母
short N2;
cin>>N2;
short father2[N2];
char data2[N2];
for(i=0;i<N2;i++)
father2[i]=i;
if(N1!=N2)
flag=0;
else{
for(i=0;i<N2;i++){
char m0,m1,m2;
cin>>m0>>m1>>m2;
data2[i]=m0;
node2[m0-'A']=i;
appear2[m0-'A']=1;
if('-'!=m1)
father2[m1-'0']=i;
if('-'!=m2)
father2[m2-'0']=i;
}
for(i=0;i<26;i++){ //检索26个字符
if(!appear1[i]&&!appear2[i])
continue; //该字符不在树中
if(!appear1[i]*appear2[i]){
flag=0;
break;
} //说明出现的字符不同
if(data1[father1[node1[i]]]!=data2[father2[node2[i]]]){
flag=0;
break;
}
}
}
if(flag)
printf("Yes");
else
printf("No");
return 0;
}
题目:7-25 朋友圈(25分)
并查集
#include <bits/stdc++.h>
using namespace std;
int N,M;
int f[30010];
int cnt[30010];
int find(int x)
{
if(f[x]==-1)
return x;
else
return f[x]=find(f[x]);
}
int fin(int x,int y)
{
int a=find(x),b=find(y);
if(a!=b)
f[b]=a;
}
int main()
{
cin>>N>>M;
memset(f,-1,sizeof f);
while(M--)
{
int Mi,x,y;
cin>>Mi;
for(int i=1;i<=Mi;i++)
{
cin>>y;
if(i==1)
x=y;
else
fin(x,y);
}
}
for(int i=1;i<=N;i++)
cnt[find(i)]++;
int ans=0;
for(int i=1;i<=N;i++)
ans=max(ans,cnt[i]);
cout<<ans;
}
题目:L2-041 插松枝(25分)
栈、队列
#include <bits/stdc++.h>
using namespace std;
int main()
{
int n,m,k,x;
cin>>n>>m>>k;
stack<int> box;
queue<int> push;
vector<int> tree;
while(n--)
{
cin>>x;
push.push(x);
}
while(1)
{
if((push.size()==0&&box.size()==0)||tree.size()==k||box.size()==m&&(push.size()==0||push.front()>tree.back())||push.size()==0&&box.top()>tree.back())
{
for(int j=0;j<tree.size();j++)
if(j>0)
cout<<" "<<tree[j];
else
cout<<tree[j];
cout<<endl;
tree.clear();
}
if(push.size()==0&&box.size()==0)//推送器和盒子里面都没有了,结束
break;
if(box.size()>0&&(tree.size()==0||box.top()<=tree.back()))//盒子里面有并且树是空的或者盒子里面的满足
{
tree.push_back(box.top());
box.pop();
}
else if(push.size()>0&&(tree.size()==0||push.front()<=tree.back()))//推送器上有并且树是空的或者推送器上的满足
{
tree.push_back(push.front());
push.pop();
}
else if(tree.size()>0&&push.front()>tree.back())//树上已经有了并且推送器上的大于树上的,把推送器上的放入盒子中
{
box.push(push.front());
push.pop();
}
}
}