AcWing 3197. 相反数
flag数组标记计数即可 暴力AC:
#include<iostream>
using namespace std;
const int N=1e3+5;
int n,flag[N],ans;
int main(){
cin>>n;
while(n--){
int x;
cin>>x;
flag[abs(x)]++;
}
for(int i=1;i<=1000;i++) if(flag[i]==2) ans++;
cout<<ans<<endl;
return 0;
}
AcWing 3198. 窗口
模拟 + map AC:
#include<iostream>
#include<cstring>
#include<map>
using namespace std;
typedef pair<int,int>pii;
typedef pair<pii,pii>piiii;
int n,m,flag[2599][1499];
map<int,piiii>mapp;
int main(){
cin>>n>>m;
memset(flag,-1,sizeof flag);
for(int i=1;i<=n;i++){
int x1,y1,x2,y2;
cin>>x1>>y1>>x2>>y2;
mapp[i]=make_pair(make_pair(x1,y1),make_pair(x2,y2));
for(int j=x1;j<=x2;j++) for(int k=y1;k<=y2;k++) flag[j][k]=i;
}
while(m--){
int x,y,ans;
cin>>x>>y;
ans=flag[x][y];
if(ans>0){
cout<<ans<<endl;
piiii t=mapp[ans];
for(int i=t.first.first;i<=t.second.first;i++)
for(int j=t.first.second;j<=t.second.second;j++)
flag[i][j]=ans;
}
else cout<<"IGNORED"<<endl;
}
return 0;
}
AcWing 3199. 命令行选项
模拟AC:
#include<iostream>
#include<map>
#include<vector>
#include<cstring>
using namespace std;
int n,flag_CS[26];// flag_CS用于标记字符是否为命令
int main(){
string s;
cin>>s;
for(int i=0;i<s.size();i++){
flag_CS[s[i]-'a']=-1;// 将字符标记为无参数命令
if(s[i]==':') flag_CS[s[i-1]-'a']=1;// 如果字符后有':',标记为有参数命令
}
cin>>n;
getchar();// 吸收换行符,避免影响后续的getline读取
for(int c=1;c<=n;c++){
string line;
getline(cin,line);// 读取一行命令
vector<string>ans;// 定义字符串向量ans,用于存储分割后的命令
string t;
// 分割命令行字符串
for(int i=0;i<line.size();i++){
if(line[i]!=' ') t+=line[i];
if(line[i]==' ') {ans.push_back(t); t="";}
if(i+1==line.size()) ans.push_back(t);
}
map<int,string>mapp;// 定义映射容器mapp,用于存储命令和对应的值
for(int i=1;i<ans.size();i++){
// 检查命令格式是否正确
if(ans[i][0]!='-'||ans[i][1]<'a'||ans[i].size()!=2) break;
int x=ans[i][1]-'a';
// 如果无参数命令
if(flag_CS[x]==-1) mapp[x]="无参数";
// 如果有参数命令
else if(flag_CS[x]==1&&(i+1)<ans.size()) mapp[x]=ans[i+1],i++;
// 如果命令格式错误,跳出循环
else break;
}
//格式化输出
cout<<"Case "<<c<<":";
for(auto x:mapp){
if(flag_CS[x.first]==-1) cout<<" -"<<(char)('a'+x.first);
else cout<<" -"<<(char)('a'+x.first)<<" "<<x.second;
}
cout<<endl;
}
return 0;
}
AcWing 3200. 无线网络
bfs+贪心 AC:
#include<iostream>
#include<cstring>
#include<vector>
#include<queue>
#include<map>
using namespace std;
typedef long long ll;
int n,m,k,r,dist[205][205];//第i个点的路径中增设路由器的数量为j的最短距离
vector<int>G[205];
map<int,pair<int,int>>mapip;
int bfs(){
memset(dist,0x3f,sizeof dist);
queue<pair<int,int>>q;
q.push({1,0});//起点编号为1,初始路由器数量为0
dist[1][0]=0;
while(!q.empty()){
auto t=q.front();
q.pop();
int id=t.first,cnt=t.second;
for(int nextp:G[id]){
int nextCnt=cnt;
if(nextp>n) nextCnt++;//如果移动到新增路由器,则计数增加
if(nextCnt<=k){//如果增设的路由器数量不超过k,则继续搜索
if(dist[nextp][nextCnt]>dist[id][cnt]+1){//如果找到更短的路径,则更新dist数组,并将新的节点加入队列
dist[nextp][nextCnt]=dist[id][cnt]+1;
q.push({nextp,nextCnt});
}
}
}
}
int ans=0x3f3f3f3f;
for(int i=0;i<=k;i++) ans=min(ans,dist[2][i]);//终点编号为2
return ans-1;
}
int main(){
cin>>n>>m>>k>>r;
for(int i=1;i<=n+m;i++){
int x,y;
cin>>x>>y;
mapip[i]=make_pair(x,y);
}
for(int i=1;i<=n+m;i++){
for(int j=i+1;j<=n+m;j++){
int ax=mapip[i].first,ay=mapip[i].second,bx=mapip[j].first,by=mapip[j].second;
if((ll)(ax-bx)*(ax-bx)+(ll)(ay-by)*(ay-by)<=(ll)r*r){
G[i].push_back(j);G[j].push_back(i);
}
}
}
cout<<bfs()<<endl;
return 0;
}
AcWing 3201. 任务调度
暴力dfs 超时(4/12):
#include<iostream>
using namespace std;
const int N=45;
int n,flag[N],ans=0x3f3f3f3f;
struct node{
int a,b,c,d;
}t[N];
void swap(int &a,int &b){
int temp=a;a=b;b=temp;
}
void dfs(int cnt,int cpu1,int cpu2,int gpu){
if(cnt==n+1){
int res=max(max(cpu1,cpu2),gpu);
if(res<ans){
ans=res;
return;
}
}
for(int i=cnt;i<=n;i++){
// 交换任务顺序
swap(flag[cnt],flag[i]);
// 尝试分配到CPU1
dfs(cnt+1,cpu1+t[flag[cnt]].a,cpu2,gpu);
// 尝试分配到CPU2
dfs(cnt+1,cpu1,cpu2+t[flag[cnt]].a,gpu);
// 尝试分配到GPU,同时更新CPU1和GPU
int res=max(cpu1,gpu)+t[flag[cnt]].c;
dfs(cnt+1,res,cpu2,res);
// 尝试分配到GPU,同时更新CPU2和GPU
res=max(cpu2,gpu)+t[flag[cnt]].c;
dfs(cnt+1,cpu1,res,res);
// 尝试同时分配到CPU1、CPU2和GPU
res=max(max(cpu1,cpu2),gpu)+t[flag[cnt]].d;
dfs(cnt+1,res,res,res);
// 恢复任务顺序
swap(flag[cnt],flag[i]);
}
}
int main(){
cin>>n;
for(int i=1;i<=n;i++) flag[i]=i;
for(int i=1;i<=n;i++){
cin>>t[i].a>>t[i].b>>t[i].c>>t[i].d;
t[i].d=min(t[i].d,t[i].b);
}
dfs(1,0,0,0);
cout<<ans<<endl;
return 0;
}
考试时候可以写出暴力解法对我来说就很好了...
动态规划 AC:
#include<iostream>
#include<cstring>
using namespace std;
const int N=50, M=210;// N为任务数量上限,M为资源使用上限
int n;
// f[u][i][j][k]表示第u个任务完成后,CPU1使用i个单位时间,CPU2使用j个单位时间,GPU使用k个单位时间的最小完成时间
int f[2][M][M][M];
// c[i][0]为CPU1需求,c[i][1]为GPU需求,c[i][2]为CPU2需求
int c[N][3];
int main(){
cin >> n;
// 初始化变量m和m2,用于计算所有任务CPU1需求的总和
int m=0, m2=0;
for(int i=1;i<=n;i++){
int x, y, z, t;
cin >> x >> y >> z >> t;
// 存储每个任务的资源需求
c[i][0] = x, c[i][1] = z, c[i][2] = min(y, t);
// 累加CPU1的总需求
m += x;
// 根据任务编号奇偶性累加CPU1的需求
if(i % 2) m2 += x;
}
// 计算最大可能的CPU1需求,用于确定动态规划数组的大小
m = max(m2, m - m2);
// 初始化动态规划数组f,表示初始状态下的完成时间为无穷大
memset(f, 0x3f, sizeof f);
// 设置初始状态,没有执行任何任务时的完成时间为0
f[0][0][0][0] = 0;
// 遍历每个任务
for(int u=1;u<=n;u++)
// 遍历CPU1的可能使用时间
for(int i=0;i<=m;i++)
// 遍历CPU2的可能使用时间
for(int j=i;j<=m;j++)
// 遍历GPU的可能使用时间
for(int k=0;k<=j;k++) // GPU不能单独使用,因此k不能大于j
{
// 获取当前状态下的完成时间
int &v = f[u & 1][i][j][k];
// 获取当前任务的资源需求
int x = c[u][0], y = c[u][1], z = c[u][2], t = (u - 1) & 1;
// 尝试不同的分配方案
v = f[t][i][j][k] + z; // 模式3:任务分配给GPU
if(i >= x) v = min(v, f[t][min(i - x, j)][max(i - x, j)][k]); // 模式1:任务分配给CPU1
if(j >= x) v = min(v, f[t][min(j - x, i)][max(j - x, i)][k]); // 模式1:任务分配给CPU2
if(i >= y && k >= y) v = min(v, f[t][i - y][j][k - y]); // 模式2:任务同时分配给CPU1和GPU
if(j >= y && k >= y) v = min(v, f[t][i][j - y][k - y]); // 模式2:任务同时分配给CPU2和GPU
}
int ans = 0x3f3f3f3f;
for(int i=0;i<=m;i++)
for(int j=i;j<=m;j++)
for(int k=0;k<=j;k++)
ans = min(ans, f[n & 1][i][j][k] + max(max(i, j), k));
cout << ans << endl;;
return 0;
}