2022年团体程序设计天梯赛-总决赛 L1 - L12

文章目录

  • 一、L1-1 今天我要赢?
  • 二、L1-2 种钻石
  • 三、L1-3 谁能进图书馆
  • 四、L1-4 拯救外星人
  • 五、L1-5 试试手气
  • 六、L1-6 斯德哥尔摩火车上的题
  • 七、L1-7 机工士姆斯塔迪奥
  • 八、L1-7 机工士姆斯塔迪奥
  • 九、L2-1 插松枝
  • 十、L2-2 老板的作息表
  • 十一、L2-3 龙龙送外卖
  • 十二、L2-4 大众情人
  • 总结


一、L1-1 今天我要赢?

直接上代码吧,不废话了

#include
#define int long long

using namespace std;
typedef pair <int, int> PII;

#define endl '\n'
#define fi first
#define se second
#define ppb pop_back
#define pb push_back
#define ios ios::sync_with_stdio(0); cin.tie(0); cout.tie(0)

#define all(x) x.begin(), x.end()
#define rall(x) x.rbegin(), x.rend()
#define mem(x, a) memset(x, a, sizeof x)
#define rep(i, l, r) for(int i = l; i <= (r); ++ i)
#define per(i, r, l) for(int i = r; i >= (l); -- i)
#define reps(i, l, r, d) for(int i = l; i <= (r); i += d)
#define pers(i, r, l, d) for(int i = r; i >= (l); i -= d)

signed main()
{
     
     cout << "I'm gonna win! Today!" << endl;
	 cout << "2022-04-23" << endl; 
    return 0;
}

二、L1-2 种钻石

#include
#define int long long

using namespace std;
typedef pair <int, int> PII;

#define endl '\n'
#define fi first
#define se second
#define ppb pop_back
#define pb push_back
#define ios ios::sync_with_stdio(0); cin.tie(0); cout.tie(0)

#define all(x) x.begin(), x.end()
#define rall(x) x.rbegin(), x.rend()
#define mem(x, a) memset(x, a, sizeof x)
#define rep(i, l, r) for(int i = l; i <= (r); ++ i)
#define per(i, r, l) for(int i = r; i >= (l); -- i)
#define reps(i, l, r, d) for(int i = l; i <= (r); i += d)
#define pers(i, r, l, d) for(int i = r; i >= (l); i -= d)

signed main()
{
    int a,b; cin >> a >> b; 
    cout << a / b << endl;

    return 0;
}

三、L1-3 谁能进图书馆

简单的模拟,关键是不要漏掉情况

#include
#define int long long

using namespace std;
typedef pair <int, int> PII;

#define endl '\n'
#define fi first
#define se second
#define ppb pop_back
#define pb push_back
#define ios ios::sync_with_stdio(0); cin.tie(0); cout.tie(0)

#define all(x) x.begin(), x.end()
#define rall(x) x.rbegin(), x.rend()
#define mem(x, a) memset(x, a, sizeof x)
#define read(i, l, r) for(int i = l; i <= (r); ++ i)
#define per(i, r, l) for(int i = r; i >= (l); -- i)
#define reps(i, l, r, d) for(int i = l; i <= (r); i += d)
#define pers(i, r, l, d) for(int i = r; i >= (l); i -= d)



signed main()
{
  
    int jr,pt,a1,a2; cin >> jr >> pt >> a1 >> a2;
    
    if(a1 >= jr && a2 >= jr)
    {
    	 cout << a1 << "-Y " << a2 << "-Y" << endl;  
    	 cout << "huan ying ru guan" << endl;
	}
	else if(a1 < jr && a2 >= pt)// 有个人没到年龄 
	{
		cout << a1 << "-Y " << a2 << "-Y" << endl;
		cout << "qing 2 zhao gu hao 1" << endl;
	}
	else if(a1 >= pt && a2 < jr)
	{
		cout << a1 << "-Y " << a2 << "-Y" << endl;
		cout << "qing 1 zhao gu hao 2" << endl;
	}
	else if(a1 < jr && a2 < jr)
	{
		cout << a1 << "-N " << a2 << "-N" << endl;
		cout << "zhang da zai lai ba" << endl;
	}
	else if(a1 >= jr)
	{
		cout << a1 << "-Y " << a2 << "-N" << endl;
		cout << "1: huan ying ru guan" << endl;
	}
	else if(a2 >= jr)
	{
		cout << a1 << "-N " << a2 << "-Y" << endl;
		cout << "2: huan ying ru guan" << endl;
	}
    
   
  
    
    return 0;
}

四、L1-4 拯救外星人

递归

#include
#define int long long

using namespace std;
typedef pair <int, int> PII;

#define endl '\n'
#define fi first
#define se second
#define ppb pop_back
#define pb push_back
#define ios ios::sync_with_stdio(0); cin.tie(0); cout.tie(0)

#define all(x) x.begin(), x.end()
#define rall(x) x.rbegin(), x.rend()
#define mem(x, a) memset(x, a, sizeof x)
#define read(i, l, r) for(int i = l; i <= (r); ++ i)
#define per(i, r, l) for(int i = r; i >= (l); -- i)
#define reps(i, l, r, d) for(int i = l; i <= (r); i += d)
#define pers(i, r, l, d) for(int i = r; i >= (l); i -= d)

signed main()
{
  
   int a,b;	cin >> a >> b;
   int res = 1;
   for(int i = 1;i <= a + b;i ++ )
   res = res * i; 
   
   cout << res << '\n';

   
  
    
    return 0;
}

五、L1-5 试试手气

思维 第一次一定是到6,第二次一定是到5以此类推.。。
如果a[i] >= d[k],代表出问题了,第一个条件无法满足,中间肯定出现过已经出现过的数字了,所以再减去1即可

#include
#define int long long

using namespace std;
typedef pair <int, int> PII;

#define endl '\n'
#define fi first
#define se second
#define ppb pop_back
#define pb push_back
#define ios ios::sync_with_stdio(0); cin.tie(0); cout.tie(0)

#define all(x) x.begin(), x.end()
#define rall(x) x.rbegin(), x.rend()
#define mem(x, a) memset(x, a, sizeof x)
#define read(i, l, r) for(int i = l; i <= (r); ++ i)
#define per(i, r, l) for(int i = r; i >= (l); -- i)
#define reps(i, l, r, d) for(int i = l; i <= (r); i += d)
#define pers(i, r, l, d) for(int i = r; i >= (l); i -= d)

const int N = 1e5 + 1000;
int a[N],b[N];
signed main()
{
  
	for(int i = 1;i <= 6;i ++ ) cin >> a[i];
	for(int i = 1;i <= 6;i ++ ) b[i] = 6 - i + 1; // 第几次变成什么 
	
	int k; cin >> k;
	for(int i = 1;i <= 6;i ++)
	{
		
		if(a[i] >= b[k]) 
		{
			if(i != 6)
			cout << b[k] - 1 << ' ';
			else
			cout << b[k] - 1;
		}
	
		else
		{	if(i != 6)
			cout << b[k] << ' ';
			else
			cout << b[k];
		}
		
	} 
   	
  
    
    return 0;
}

六、L1-6 斯德哥尔摩火车上的题

简单字符串问题,直接复制题目的代码,修改一下即可

#include
#define int long long

using namespace std;
typedef pair <int, int> PII;

#define endl '\n'
#define fi first
#define se second
#define ppb pop_back
#define pb push_back
#define ios ios::sync_with_stdio(0); cin.tie(0); cout.tie(0)

#define all(x) x.begin(), x.end()
#define rall(x) x.rbegin(), x.rend()
#define mem(x, a) memset(x, a, sizeof x)
#define read(i, l, r) for(int i = l; i <= (r); ++ i)
#define per(i, r, l) for(int i = r; i >= (l); -- i)
#define reps(i, l, r, d) for(int i = l; i <= (r); i += d)
#define pers(i, r, l, d) for(int i = r; i >= (l); i -= d)

const int N = 1e5 + 1000;
signed main()
{
  
	string a,b,s1,s2;
	cin >> a >> b;
	
	
	for (int i = 1; i < a.size(); i++) 
  	if (a[i] % 2 == a[i-1] % 2) 
	s1 += max(a[i], a[i-1]);

	for (int i = 1; i < b.size(); i ++ ) 
  	if (b[i] % 2 == b[i-1] % 2) 
	s2 += max(b[i], b[i-1]);
	
	if(s1 == s2) cout << s1 << endl;
	else
	{
		cout << s1 << endl << s2 << endl;
	}
	
	return 0;
}

七、L1-7 机工士姆斯塔迪奥

用两个bool数组 来标记行和列不能选的状态,然后枚举每一个位置,如果行或者列被标记过,就跳过去 否则记录一下

#include
#define int long long

using namespace std;
typedef pair <int, int> PII;

#define endl '\n'
#define fi first
#define se second
#define ppb pop_back
#define pb push_back
#define ios ios::sync_with_stdio(0); cin.tie(0); cout.tie(0)

#define all(x) x.begin(), x.end()
#define rall(x) x.rbegin(), x.rend()
#define mem(x, a) memset(x, a, sizeof x)
#define read(i, l, r) for(int i = l; i <= (r); ++ i)
#define per(i, r, l) for(int i = r; i >= (l); -- i)
#define reps(i, l, r, d) for(int i = l; i <= (r); i += d)
#define pers(i, r, l, d) for(int i = r; i >= (l); i -= d)

const int N = 1e5 + 1000;
bool row[N],column[N];
signed main()
{
  	int n,m,q; cin >> n >> m >> q;
  	
  	while(q -- )
  	{
  		int op,x; cin >> op >> x;
  		if(op == 0) 
  		row[x] = true;
  		else
  		column[x] = true;
	}
	int ans = 0;
	for(int i = 1;i <= n;i ++ )
	{
		for(int j = 1;j <= m;j ++ )
		if(row[i] || column[j]) continue;
		else
		ans++;
	}
	
	cout << ans << endl;
	
	return 0;
}

八、L1-7 机工士姆斯塔迪奥

用一个结构题来排一下序列,如果这个PAT成绩是大于题目给定的值s的话,实际上就只占用一批,

#include
#define int long long

using namespace std;
typedef pair <int, int> PII;

#define endl '\n'
#define fi first
#define se second
#define ppb pop_back
#define pb push_back
#define ios ios::sync_with_stdio(0); cin.tie(0); cout.tie(0)

#define all(x) x.begin(), x.end()
#define rall(x) x.rbegin(), x.rend()
#define mem(x, a) memset(x, a, sizeof x)
#define read(i, l, r) for(int i = l; i <= (r); ++ i)
#define per(i, r, l) for(int i = r; i >= (l); -- i)
#define reps(i, l, r, d) for(int i = l; i <= (r); i += d)
#define pers(i, r, l, d) for(int i = r; i >= (l); i -= d)

const int N = 1e5 + 1000;
struct node
{
	int tts,pat;	
}e[N];
bool st[N];
bool cmp(node x,node y)
{
	if(x.tts != y.tts) return x.tts < y.tts;
	
	return x.pat > y.pat;
} 

signed main()
{

	int n,k,s; cin >> n >> k >> s;
	int cnt = 0; // 有多少个符合条件的 
	
	for(int i = 1;i <= n;i ++ )
	{
		int tts,pat; cin >> tts >> pat;
		if(tts < 175) continue;
		e[++cnt].tts = tts;
		e[cnt].pat = pat;
	}
	
	sort(e + 1,e + 1 + cnt,cmp); // 让天梯赛分数从小到大,让PAT分数从大到小 
	int ans = 0;// 记录被选的人数
	int res = 0;
	e[0].tts = -1;
	
	for(int i = 1;i <= cnt;i ++ )
	{
		if(st[e[i].tts]) continue;// 这个天梯赛分数不能再被选了 
		if(e[i].tts != e[i - 1].tts) res = 0; // 来一个新的天梯赛分数就更新res
		
		if(res < k)
		{
			if(e[i].pat < s)//这个需要消耗批次
			res++;
			
			ans++;
		}
		else
		{
			st[e[i].tts] = true;
			res = 0;
		}
		
		
	}
	
	cout << ans << endl;
	
	return 0;
}

九、L2-1 插松枝

模拟,有点细节需要注意,就是推送器上面的推完以后,还得考虑一下盒子里面的

#include

using namespace std;

const int N = 1e3 + 100;
stack<int> res[N];
stack<int> box,pusher;
int a[N],cnt = 0;

int main()
{
	int n,m,k; cin >> n >> m >> k; 
	
	for(int i = 1;i <= n;i ++ ) cin >> a[i];
	for(int i = n;i >= 1;i -- ) pusher.push(a[i]); // 左边要是底部,所以要从后面往前面插入
	
	while(pusher.size()) // 推送器不空
	{
		int t = pusher.top();// 推送器顶端
		
		if(box.size() == 0)  // 小盒子如果是空的,那就拿推送器顶端的 
		{
			if(res[cnt].size() == 0) //如果这个还没有插树叶
			{
				res[cnt].push(t);
				if(res[cnt].size() == k) cnt++; // 不能插树叶,换一根树枝 
				pusher.pop();
			}
			else
			{
				if(t <= res[cnt].top()) // 如果符合条件 
				{
					res[cnt].push(t);
					if(res[cnt].size() == k) cnt++; // 不能插树叶,换一根树枝 
					pusher.pop();
				}
				else // 放入盒子里面 
				{
					box.push(t);
					if(res[cnt].size() == k) cnt++; // 不能插树叶,换一根树枝 
					pusher.pop();
				}
			}
			
		
		}
		else
		{
			int u = box.top(); // 先判断小盒子顶部,不符合再判断推送器顶部
			if(res[cnt].size() == 0) //如果这个还没有插树叶
			{
				res[cnt].push(u);
				if(res[cnt].size() == k) cnt++; // 树枝插满了,换下一根树枝 
				box.pop();
			}
			else
			{
			    int p = res[cnt].top();
			    if(res[cnt].size() == k) cnt++; // 树枝插满了,换下一根树枝 
			    
				if(u <= p)// 先判断小盒子顶部
				{
					res[cnt].push(u);
					if(res[cnt].size() == k) cnt++; // 树枝插满了,换下一根树枝 
					box.pop();
				}
				else if(t <= p)//再判断推送器顶部
				{
					res[cnt].push(t);
					if(res[cnt].size() == k) cnt++; // 树枝插满了,换下一根树枝 
					pusher.pop();
				}
				else // 放入小盒子顶部 
				{
					if(box.size() == m)// 小盒子已经满了,并且顶部不符合条件,再拿一个新树枝 
					{
						cnt++;
					}
					else
					{
						box.push(t);
						pusher.pop();
					} 
				}
			}
			
			
		} 
	} 
	while(box.size()) // 小盒子里面还有,清空小盒子里面的
	{
	    int u = box.top();
	    if(res[cnt].size() == 0)
	    {
	        res[cnt].push(u);
	        box.pop();
	    }
	    else if(u <= res[cnt].top())
	    {
	        res[cnt].push(u);
	        box.pop();
	    }
	    else
	    cnt++;
	    
	    if(res[cnt].size() == k)
	    cnt++;
	    
	}
	
	for(int i = 0;i <= cnt;i ++ )
	{
		int c[N],d = 0;
		while(res[i].size())
		{
			int q = res[i].top();res[i].pop();
			c[++d] = q;
		}
		
		for(int j = d;j >= 1;j -- )
		{
			if(j != 1)
			cout << c[j] << ' ';
			else
			cout << c[j] << endl;
		}
	} 
	
	return 0;
}

十、L2-2 老板的作息表

这个我的思路是,把他们全部变成秒,来判断,用一个结构体来存开始的秒,与结束的秒,再对结构体排序,如果某一个结束的秒与下一个开始的秒之间有距离就记录一下,然后输出

#include

using namespace std;

const int N = 1e5 + 100;

struct node
{
    int st,ed;
}e[N];
bool cmp(node x,node y)
{
    if(x.st != y.st)
    return x.st < y.st;
    
    return x.ed < y.ed;
}
int main()
{
    int n; scanf("%d",&n);
    for(int i = 1;i <= n;i ++ )
    {
        int stx,stm,sts,edx,edm,eds;
        scanf("%d:%d:%d - %d:%d:%d", &stx,&stm,&sts,&edx,&edm,&eds);
        
        int st = (stx * 60 + stm) * 60 + sts;
        int ed = (edx * 60 + edm) * 60 + eds;
        e[i] = {st,ed};
    }
    
    sort(e + 1,e + 1 + n,cmp);
    
	e[n + 1].st = (23 * 60 + 59) * 60 + 59;
	e[n + 1].ed = (23 * 60 + 59) * 60 + 59;
	int st = 0,ed = 0;
	for(int i = 1;i <= n + 1;i ++ )
	{
	       if(ed < e[i].st)
	       {
	           int stx,stm,sts,edx,edm,eds;
	           
	           stx = ed / 3600;
	           stm = (ed - stx * 3600) / 60;
	           sts = ed - stx * 3600 - stm * 60;
	           
	           edx = e[i].st / 3600;
	           edm = (e[i].st - edx * 3600) / 60;
	           eds = e[i].st - edx * 3600 - edm * 60;
	           
	           printf("%02d:%02d:%02d - %02d:%02d:%02d\n",stx,stm,sts,edx,edm,eds);
	          
	       }
	       st = e[i].st;
	       ed = e[i].ed;
	}
	
	return 0;
}

十一、L2-3 龙龙送外卖

dfs + 贪心,就是最长的路就是走一遍就好,其他路走两遍,因为有一个来回, 我们可以让所有的路走两遍,最后减去最长的路的步数。从当前节点一直往上走,直到找到根节点或者找到被标记过的节点,就结束递归

#include
#define int long long

using namespace std;
typedef pair <int, int> PII;

#define endl '\n'
#define fi first
#define se second
#define ppb pop_back
#define pb push_back
#define ios ios::sync_with_stdio(0); cin.tie(0); cout.tie(0)

#define all(x) x.begin(), x.end()
#define rall(x) x.rbegin(), x.rend()
#define mem(x, a) memset(x, a, sizeof x)
#define rep(i, l, r) for(int i = l; i <= (r); ++ i)
#define per(i, r, l) for(int i = r; i >= (l); -- i)
#define reps(i, l, r, d) for(int i = l; i <= (r); i += d)
#define pers(i, r, l, d) for(int i = r; i >= (l); i -= d)

const int N = 1e5 + 1000;
bool st[N]; // 被走过了就标记一下
int d[N],fa[N];// fa[i] 就是i的父节点是谁,
vector<int> res[N];
int ans;
int n,q,root;
void dfs1(int u,int depth) // 预处理一下每一个节点在第几层
{
    int len = res[u].size() - 1;
    rep(i,0,len)
    {
        int j = res[u][i];
        dfs1(j,depth + 1);
    }
    
    d[u] = depth;
}
void dfs2(int u)
{
    if(st[u] || u == root ) return;
    st[u] = true;
    ans += 2;
    dfs2(fa[u]);
    
}

signed main()
{
    cin >> n >> q;
    for(int i = 1;i <= n;i ++ )
    {
        int x;  cin >> x;
        if(x == -1)
        {
            root = i;
            fa[i] = i;
        }
        else
        {
            res[x].pb(i);
            fa[i] = x;// 这个因为只有一个双亲,所以用一个就行了
        }
        
    }
    dfs1(root,1);
   
   
    int mx = -1; // 最大深度
    while(q -- )
    {
        int x; cin >> x;
        if(st[x]) cout << ans - mx + 1<< endl;// 如果出现过
        else
        {
           	mx = max(d[x],mx);	 
            
            dfs2(x);
			cout << ans - mx + 1 << endl;
        }
    }
    
    
    return 0;
}

十二、L2-4 大众情人

典型的Floyd求最短路,需要注意的是 假如两个节点 a - > b 是 1,那 b- > a 可不是1 ,也就是说这是一个有向图,最后注意 因为是 要找 异性缘最大的,所以枚举每一个男人,判断枚举每一个女人对男人的距离感,取最大值,同理,对于女人也一样

#include
#define int long long

using namespace std;
typedef pair <int, int> PII;

#define endl '\n'
#define fi first
#define se second
#define ppb pop_back
#define pb push_back
#define ios ios::sync_with_stdio(0); cin.tie(0); cout.tie(0)

#define all(x) x.begin(), x.end()
#define rall(x) x.rbegin(), x.rend()
#define mem(x, a) memset(x, a, sizeof x)
#define rep(i, l, r) for(int i = l; i <= (r); ++ i)
#define per(i, r, l) for(int i = r; i >= (l); -- i)
#define reps(i, l, r, d) for(int i = l; i <= (r); i += d)
#define pers(i, r, l, d) for(int i = r; i >= (l); i -= d)

const int N = 1550;
vector<int> man,woman;
int d[N][N];
int n;
struct node
{
    int id;
    int dis;
}e[N],e2[N];

bool cmp(node x,node y)
{
    if(x.dis != y.dis) return x.dis < y.dis;
    
    return x.id < y.id;
}

void floyd()
{
    rep(k,1,n)
    {
        rep(i,1,n)
        {
            rep(j,1,n)
            d[i][j] = min(d[i][j],d[i][k] + d[k][j]);
        }
    }
}
signed main()
{
     
     scanf("%lld",&n);
     memset(d,0x3f,sizeof d);
     rep(i,1,n)
     {
         rep(j,1,n)
         if(i == j)
         d[i][j] = 0;
     }
     
     for(int i = 1;i <= n;i ++ )
     {
         char sex;cin >> sex;
         int k; scanf("%lld",&k);
         
          if(sex == 'F') woman.pb(i);
          else man.pb(i);
         
         rep(j,1,k)
         {
             int id,dis; scanf("%lld:%lld",&id,&dis);
             d[i][id] = min(dis,d[i][id]);
         }
         
     }
     floyd();
     
     int len = man.size();
     int cnt = 0,cnt2 = 0;
    
      rep(i,0,len - 1)
      {
         int len2 = woman.size();
         int mx = -1;
         rep(j,0,len2 - 1)
         {
             
             mx = max(mx,d[woman[j]][man[i]]);
         }
         e2[++cnt2] = {man[i],mx};
      }

     len = woman.size();
     rep(i,0,len - 1)
     {
         int len2 = man.size();
         int mx = -1;
         rep(j,0,len2 - 1)
         {
            
             mx = max(mx,d[man[j]][woman[i]]);
         }
         e[++cnt] = {woman[i],mx};
     }
     
     sort(e + 1,e + 1 + cnt,cmp);
     sort(e2 + 1,e2 + 1 + cnt2,cmp);
     
     cout << e[1].id;
     rep(i,2,cnt)
     if(e[i].dis == e[1].dis)
     cout << ' ' << e[i].id;
     else
     break;
     
     cout << endl;
     
     cout << e2[1].id;
     rep(i,2,cnt2)
     if(e2[i].dis == e2[1].dis)
     cout << ' ' << e2[i].id;
     else
     break;
     
     cout << endl;
     
    return 0;
}

总结

**这次的天梯赛,说实话自己写的很不好,啥也不会也不愿意学,心态不行,心态出问题了,以后每天都要反思自己,别把自己当回事,有太多的人比你厉害的多,时刻题提醒自己永远是一个学习者.

关于这次天梯赛出的题,我自己有点感悟

1 就是这次出的题目是更加注重对细心的考察,有几道题就是如此,比如第一个那个插树叶的那道题,其实并不难,就是考察了很多细节,你仔细一点,一步一步写不要着急,应该能拿满分

2 自己打天梯赛太稳了,稳的状态下,就是慢,导致写完第二个25分的题,就剩下一点时间了,这个说好也不好,对于acm来说,稳一点是好的,因为提交错误会罚时,但是对于天梯赛来说,并不会算这个时间,所以这也是经验上的欠缺.(内部逻辑 == 还是自己太菜了,啥也不是)

3 就是最后剩下的时间有点着急了,就是心里面一直乱,没有办法保持一个平常心去打比赛,我觉得是这是兵家大忌(对于打acm的选手来说),因为打编程比赛,冷静是第一位的,自己平时的磨练还是不够,这点需要加强一下,(每天拿出两个小时来写一套cf),当成比赛一样

你可能感兴趣的:(c++,贪心算法,深度优先,数据结构)