2018-2019 ICPC Southwestern European Regional Programming Contest (SWERC 2018)
2018-2019 ICPC西南欧区域编程大赛(SWERC 2018)
A - City of Lights
Gym - 102465A
水题
题意:
给n个灯,给m个数字,对于每个数字k[i]
将k[i]整数倍的灯的状态反转,(熄灭已经点亮的灯或者点亮了未点亮的灯)
初始状态灯都是亮的
问同一时刻最多亮了多少灯。
思路: 暴力即可,用上了前缀和?
代码:
思维题,前缀和
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
#define PII pair<int, int>
#define x first
#define y second
const int maxn = 1e6 + 10;
const int INF = 0x3f3f3f3f;
const ll M = 1e9 + 7;
const int N = 110;
int vis[maxn];
int main()
{
int n; cin>>n;
int k; cin>>k;
int ans=0;
int cnt=0;
for(int i=0;i<k;i++){
int t; cin>>t;
for(int j=t;j<=n;j+=t){
// cout<<j;
if(vis[j]==1){
vis[j]=0;
cnt--;
}
else {
vis[j]=1;
cnt++;
}
}
// cout<<endl;
ans=max(ans,cnt);
}
cout<<ans<<endl;
return 0;
}
B - Blurred Pictures
Gym - 102465B
题意:
给一个相片,有1×1的像素构成的,但是损伤了一些像素,
给出每一行没有损坏的像素的起始坐标,从中割除最大的没有损坏的正方形相片。
而且:在两个非模糊像素之间的任何水平或垂直线都是非模糊像素。
也就是:
给出m行的起始点坐标,判断形成的最大的正方形的个数。
思路:
由于
在两个非模糊像素之间的任何水平或垂直线都是非模糊像素。
所以只需要关心上界和下界即可,然后暴力枚举即可。
代码:
居间操作
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
#define PII pair<int, int>
#define x first
#define y second
const int maxn = 1e6 + 10;
const int INF = 0x3f3f3f3f;
const ll M = 1e9 + 7;
const int N = 10010;
int l[maxn];
int r[maxn];
int main()
{
int n;cin>>n;
int ans=1;
for(int i=0;i<n;i++) cin>>l[i]>>r[i];
for(int i=0;i<n;i++){
while(1){
if(r[i]-l[i]<=ans-1) break;//如果小于ans的话,直接下一行即可
int topX=i+ans-1+1;
if(topX>=n) break;//如果超出上边界,结束
int L=max(l[i],l[topX]);
int R=min(r[i],r[topX]);
if(R-L>=ans) ans++;
else break;
}
}
cout<<ans<<endl;
return 0;
}
D - Monument Tour
Gym - 102465D
题意:
从矩形的左边任一条路(东西走向)进入,然后参观所有的纪念碑与博物馆,只能向上或向下移动,参观完纪念碑与博物馆后返回到进入时的那条路上,求走出城市时的最短路程。
思路:
遍历x坐标轴,求出每个x坐标中的最大与最小y值,存入数组a中。
排序数组a,求出中位数,这个中位数就是汽车进入城市时的y坐标,
然后计算从0—X汽车参观每个博物馆走的路程。
代码:
思维题
#include<bits/stdc++.h>
using namespace std;
int l[100100];
int r[100100];
int a[200100];
int main()
{
int n,m,k;
cin>>n>>m>>k;
memset(l,0x3f3f3f,sizeof(l));
memset(r,-1,sizeof(r));
for(int i=1;i<=k;i++)
{
int x;
cin>>x>>a[i];
l[x]=min(l[x],a[i]);
r[x]=max(r[x],a[i]);
}
k=0;
for(int i=0;i<n;i++)
{
if(r[i]<0) continue;
a[++k]=l[i];
a[++k]=r[i];
}
sort(a+1,a+k+1);
long long res=n-1;
for(int i=0;i<n;i++)
{
if(r[i]<0) continue;
if(a[k/2]<=l[i]) res+=(r[i]-a[k/2])*2;
else if(a[k/2]>=r[i]) res+=(a[k/2]-l[i])*2;
else res+=(r[i]-l[i])*2;
}
cout<<res<<endl;
return 0;
}
E - Rounding
Gym - 102465E
题意:
总共10000个人,做了一项调查,统计出了数据,但是把这个数据的所有结果都四舍五入了,问你找出结果的最大值和最小值,也有结果不对的情况
思路:
其他最大,这个值本身最小。
其他最小,这个值本身最大。
然后判断边界,看代码吧
代码:
思维
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
#define PII pair<int, int>
#define x first
#define y second
const int maxn = 1e6 + 10;
const int INF = 0x3f3f3f3f;
const ll M = 1e9 + 7;
const int N = 10010;
int n;
string str[N];
double cnt = 0.00;
double ans[N][3];
int main()
{
cin >> n;
for (int i = 0; i < n; i++)
{
cin >> str[i];
cin >> ans[i][0];
cnt += ans[i][0];
}
double maxcnt = cnt + n * 0.49;
double minicnt = cnt - n * 0.50;
// cout<<minicnt<<" "<<maxcnt <<endl;
if (minicnt > 100.00 || maxcnt < 100.00)
{
cout << "IMPOSSIBLE" << endl;
return 0;
}
for (int i = 0; i < n; i++)
{
double t = ans[i][0];
ans[i][1] = max(t - 0.50, 100 - (maxcnt - t - 0.49)); //小
ans[i][2] = min(t + 0.49, 100 - (minicnt - t + 0.5)); //大
if( ans[i][2]>=100) ans[i][2]=100.0;
if( ans[i][1]<=0) ans[i][1]=0.00;
cout << str[i] << " ";
printf("%.2lf %.2lf\n", ans[i][1], ans[i][2]);
}
return 0;
}